Hello nebular-team,
as stated in the issue "NbAuthJWTToken from Response Header" #691 :
_Originally posted by @applicationuser in https://github.com/akveo/nebular/issues/691#issuecomment-429504707_
The token should be read as JWT token ...
this.authService.onTokenChange().subscribe(
(token:NbAuthJWTToken) =>{
BUT the output tells us that it shows a SIMPLE token:
That is why the payload is null, and every other JWT function, like "getTokenExpDate()" does not work.
I am experiencing this problem right now, but it is different for the main browser types.
token.constructor.name returns in console :
For (Linux) Firefox (V.64), Opera (V.58) (obviously using the NB_AUTH_FALLBACK_TOKEN), which is "NbAuthSimpleToken" by default.
Also (Windows) Edge, Chrome(V.71), showing:
[DEBUG] Class of Token: NbAuthSimpleToken
For (Linux) Iron (=Chrome (V. 69)) I see:
[DEBUG] Class of Token: NbAuthJWTToken
and everything works!
I found that "authservice" as injection within the HeaderComponent provides the wrong type of class in the beginning.
I am using the config as stated in the #691 :
NbPasswordAuthStrategy.setup({
name: 'user'
, token: {
class: NbAuthJWTToken ,
getter: ( module: string,
res: HttpResponse<Object>,
options: NbPasswordAuthStrategyOptions)
=> res.headers.get('Authorization')
}
to get the token out of the header, instead of the body of response.
We generate the token wit io.jsonwebtoken library :+1:
String token = Jwts.builder()
.setSubject(user)
.claim("groups", new String[] { "admin", "customer" })
.claim("mail", "[email protected]")
.signWith(SignatureAlgorithm.HS512, "sometext")
.setExpiration(exprirationDate)
.compact();
There should not be a problem with that, because at least ONE browser can read it correct.
All browsers should receive and use the token with the "NbAuthJWTToken" class.
Maybe this is a security feature or something, or maybe another provider entry is needed.
The token is correctly transferred in "Authorization" header and is printed like expected: (token hash changed for security reasons in this output):
authorization , Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhc2xpbmdvIHRlc3QgdG9rZW4iLCJncm91cHMiOlsiYWRtaW4iLCJjdXN0b21lciJdLCJtYWlsIjoibWF4QG11c3Rlcm1hbi5jb20iLCJleHAiOjE1NDg4NDU5OTN9.wy-Y0CF_PCaMd2VNE3naiwqxoE2WjKO8ibMaZdRZdmCIVEUQCm1RuVBT9IOVuKxFR2YpbCesQ
All "allow" headers are set :
response.addHeader("Access-Control-Expose-Headers",
... some other headers ...
+ "Access-Control-Allow-Credentials,"
+ "Access-Control-Allow-Methods,"
+ "Access-Control-Allow-Headers,"
+ "Authorization"
);
response.addHeader("Access-Control-Allow-Headers",
... some other headers ...
+ "Access-Control-Allow-Credentials,"
+ "Access-Control-Request-Headers,"
+ "Access-Control-Request-Method,"
+ "Access-Control-Expose-Headers"
+ "Authorization,"
);
I did not do a login first ... after calling the login component of nebular, the token is valid and seen as NbAuthJWTToken!
The login-component stores the token in the localStorage of browser and THEN other components can read with "this.authService.onTokenChange()" .
Maybe a little hint in the docs for this, under "Use Token" ?? :)
Sorry for this unnecessary entry, but maybe it will help someone sometime.
Please mark as SOLVED !
We'll update the docs.
I am also have the exact same problem, where the token is seen as NbAuthSimpleToken (e.g. on this.authService.onTokenChange()) instead of NbAuthJWTToken, although in the Nebular login component, the token is seen as type of NbAuthJWTToken.
How exactly do you resolve this issue? The OP's answer didn't really explain much.
You cannot read a token with ".onTokenChange()" as long as you called the login() function, which does a authenticate request and receives a valid token. So, after login component has been called, the token is going to be stored in localStorage of browser.
AFTER this, you can read it with ".onTokenChange()".
I tested the header component with ".onTokenChange()", but without doing a login first, so no token to work with.
So ... I did resolve this issue exactly with ... call login-component ".authenticate()" BEFORE call ".onTokenChange()".
Nope, this isn't a solution for me. I am using the nblogin template, which calls the authenticate method upon logging in. After which I call onTokenChange(), I still receive the problem.
My problem was that I was configuring my auth in my auth module instead of my app module (i.e. NbAuthModule.forRoot...) --> moving this into the app.module resolved the issue.
Hello,
I'm using ngx-admin, and I having the same problem .
I'm using NbAuthJWTToken but in header component with event onTokenChange, token.getPayload returns null, I can see that de JTW in the response is type NbAuthSimpleToken.
Anyone can help me with this.
Thanks in advanced.
Oscar
Hello,
I'm doing debug on file .../node_modules/@nebular/auth/fesm2015/index.js.
I can see that executes getPayload() of NbAuthJWTToken, and execute decodeJwtPayload(payload) , and returns the JSON decoded payload of my token. But when I want to decode the payload loaded in header.component.ts with token.getPayload() the token is of type NbAuthSimpleToken in place of NbAuthJWTToken. For this the decode token returns null.
Any one can help me please.
Hello,
I'm doing debug on file .../node_modules/@nebular/auth/fesm2015/index.js.
I can see that executes getPayload() of NbAuthJWTToken, and execute decodeJwtPayload(payload) , and returns the JSON decoded payload of my token. But when I want to decode the payload loaded in header.component.ts with token.getPayload() the token is of type NbAuthSimpleToken in place of NbAuthJWTToken. For this the decode token returns null.
Any one can help me please.
Hello @bitos2002, the solution is move "NbAuthModule.forRoot..." to core.module.ts, exactly inside export const NB_CORE_PROVIDERS. An example:
export const NB_CORE_PROVIDERS = [
...NbAuthModule.forRoot({
strategies: [
DefaultPasswordStrategy.setup({
name: 'Default',
token: {
class: NbAuthJWTToken,
key: 'token',
},
Most helpful comment
My problem was that I was configuring my auth in my auth module instead of my app module (i.e.
NbAuthModule.forRoot...) --> moving this into the app.module resolved the issue.