We’re working on building direct support for the auth code + PKCE flow into the okta-angular library.
In the meantime, the okta-auth-js library (which the angular library depends on) already has this support built in AND it does the heavy lifting for you.
Check out this repo: https://github.com/dogeared/okta-auth-js-pkce-example. In particular: https://github.com/dogeared/okta-auth-js-pkce-example/blob/master/src/auth/index.js
The important bits are the setup:
const oktaAuth = new OktaAuth({
issuer: ISSUER,
clientId: CLIENT_ID,
redirectUri: REDIRECT_URL,
grantType: 'authorization_code'
});
Notice the grantType is authorization_code
the login request:
export async function loginOkta() {
oktaAuth.token.getWithRedirect({
responseType: 'code',
scopes: ['openid', 'profile', 'email'],
});
}
Notice the responseType is code
and the redirect handler:
export async function redirect() {
oktaAuth.token.parseFromUrl()
.then((tokens) => {
tokens.forEach((token) => {
if (token.idToken) {
oktaAuth.tokenManager.add('id_token', token);
} else if (token.accessToken) {
oktaAuth.tokenManager.add('access_token', token);
}
});
router.push('/profile');
})
.catch(console.error);
}
the parseFromUrl function does two things:
- detects that there’s a code in the url (as opposed to the implicit flow, where there would be tokens in the url)
- creates the POST request to the /token endpoint and executes it
parseFromUrl returns a promise which is resolved in the then() function.
It iterates over the passed in tokens and makes the appropriate call to the tokenManager.add function:
oktaAuth.tokenManager.add('id_token', token);
Notice that what’s stored in the tokenManager is NOT the raw jwt, but rather an object that includes the jwt.
That’s why you were getting the error you posted above.
HTH!