I’m using ASP.Net Core Identity to store user info in JWT Token. I found that there is a problem with decoding the token that consists of Url Photo from Facebook.
Here is the way I’m decoding the token with javascript:
JSON.parse(atob(token.split('.')[1]));
and it results in the following error:
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Referring to this post I think that there must be some replacement in the back-end with C# on the photo URL. I applied the changes but it wasn’t useful.
Here is the URL I got from Facebook:
https://scontent-ams4-1.xx.fbcdn.net/v/t1.30497-1/84628273_176159830277856_972693363922829312_n.jpg?stp=c15.0.50.50a_cp0_dst-jpg_p50x50&_nc_cat=1&ccb=1-7&_nc_sid=12b3be&_nc_ohc=D3l7nXsZ3NgAX_SAb-s&_nc_ht=scontent-ams4-1.xx&edm=AP4hL3IEAAAA&oh=00_AT8ViyxqwFycpp5TQRkSMoM34pivsmHOhPZSVJfrdYMRdw&oe=62C47219
UPDATE:
Create a token that include photo Url received from Facebook.
public async Task<DtoAuthenticationResult> CreateTokenAsync(AppUser user) { var claims = new List<Claim> { new ("UserName", user.UserName), new ("PhotoUrl", user.ProfilePhotoUrl), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), }; var roles = await _userManager.GetRolesAsync(user); claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role))); var cred = new SigningCredentials(_key, SecurityAlgorithms.HmacSha512); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), //Expires = DateTime.Now.Add(_jwtSettings.TokenLifeTime), Expires = DateTime.UtcNow.AddSeconds(120), SigningCredentials = cred }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return new DtoAuthenticationResult { Success = true, Token = tokenHandler.WriteToken(token) }; }
client-side:
export class UserToken { token: string; success: string; errors: string[]; } facebookAuth(model: SocialUser) { return this.http.post(this.baseUrl + 'account/facebookAuth', model) .pipe(map((response: UserToken) => { const user = response; this.setCurrentUser(response); })); } setCurrentUser(authResult: UserToken) { const user: User = this.getDecodedToken(authResult.token); ... } getDecodedToken(token: string) : User { let u = JSON.parse(atob(token.split('.')[1])); let usr = new User(); ... }
Update 2:
Token value :
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6Ik5pY2suZnVyeWZjYkBnbWFpbC5jb20iLCJJZCI6IjIwMCIsIlVzZXJOYW1lIjoiTmljayIsIlNleCI6IjAiLCJHZW5kZXIiOiIwIiwiUGhvdG9VcmwiOiJodHRwczovL3Njb250ZW50LWFtczQtMS54eC5mYmNkbi5uZXQvdi90MS4zMDQ5Ny0xLzg0NjI4MjczXzE3NjE1OTgzMDI3Nzg1Nl85NzI2OTMzNjM5MjI4MjkzMTJfbi5qcGc_c3RwPWMxNS4wLjUwLjUwYV9jcDBfZHN0LWpwZ19wNTB4NTAmX25jX2NhdD0xJmNjYj0xLTcmX25jX3NpZD0xMmIzYmUmX25jX29oYz1EM2w3blhzWjNOZ0FYX1NBYi1zJl9uY19odD1zY29udGVudC1hbXM0LTEueHgmZWRtPUFQNGhMM0lFQUFBQSZvaD0wMF9BVDhWaXl4cXdGeWNwcDVUUVJrU01vTTM0cGl2c21IT2hQWlNWSmZyZFlNUmR3Jm9lPTYyQzQ3MjE5IiwianRpIjoiZTFkMGZkZjktMjg2MS00NzUxLWJlY2ItYzM1MjRhZDY0YWEzIiwibmJmIjoxNjU0Njk2MDA0LCJleHAiOjE2NTQ2OTYxMjQsImlhdCI6MTY1NDY5NjAwNH0.MZRvz57yjCmtkZyCDfGu3RX2LZ3KglnMM3ZzTFE73Ln7TrPyQ5_EgeWr2w0fBLOIObN6KSs9Bwvcoya7gSf7Kg
Advertisement
Answer
You need to convert base64url
encoding to the usual base64
first. Please Try this code:
var base64Url = token.split('.')[1]; var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); console.log(JSON.parse(jsonPayload));