Reputation: 2256
On the client, I have the following function that calls the server api to register a user. The user token is returned and put in localstorage.
public register = (user) => {
this.httpClient.post<User>(this.url, user).pipe(
tap(userData => {
console.log('userData register.userData', userData)
localStorage.setItem('userToken', JSON.stringify(userData.token));
// this.router.navigate(['/home']);
})
).subscribe(),
catchError(error => {
console.log('error', error)
this.store.dispatch(messageActions.SetError({error}))
throw error;
})
}
A copy of the token is seen here:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTRkNzc4MzFkMGUxN2ZiZTI1MDMyM2EiLCJpYXQiOjE2OTk1NzU3ODQsImV4cCI6MTY5OTU3NzU4NH0.3HsdFjARnAjWn35_VlXsJQ6oFbfL_3OLHTPsroIOayU"
An interceptor appends the token to the header for every request to the server as shown here:
intercept(request: HttpRequest<unknown>, next: HttpHandler):
Observable<HttpEvent<unknown>> {
const token = localStorage.getItem('userToken');
console.log('token', token)
if(token) {
// const authReq = req.clone({setHeaders:{token:token}});
const authReq = request.clone({setHeaders:{"Authorization":"Bearer " + token}});
console.log('authReq', authReq)
return next.handle(authReq)
}
return next.handle(request);
}
}
These are the stripped-down codes on the server side that pertains to creating the token:
exports.register = async (req, res) => {
try {
let userData = {};
userData.token = generateAccessToken(newUser._id);
userData.cart = cart;
console.log("userData", userData);
return res.status(201).json(userData)
} catch (error) {
console.log(error);
res.status(500).send('Problem signing up user!')
// throw error;
}
};
function generateAccessToken(userId) {
return jwt.sign({ userId }, process.env.JWT_SECRET, { expiresIn: '1800s' });
}
function authenticateToken(req, res) {
const authHeader = req.headers.authorization
console.log('authHeader', authHeader)
const token = authHeader && authHeader.split(' ')[1]
console.log('token', token)
try {
if (token == null) return res.status(500).send('Problem authenticating user token.')
const {
userId
} = jwt.verify(token, process.env.JWT_SECRET)
return userId;
} catch(err) {
console.log(err);
res.status(500).send('Problem authenticating user token.')
}
}
This is a copy of the token transmitted from transmitted from the interceptor to the server. (The 'Bearer ' is stripped off, of course.
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTRkNzc4MzFkMGUxN2ZiZTI1MDMyM2EiLCJpYXQiOjE2OTk1NzU3ODQsImV4cCI6MTY5OTU3NzU4NH0.3HsdFjARnAjWn35_VlXsJQ6oFbfL_3OLHTPsroIOayU"
The authenticateToken function errors out when jwt.verify is called with the message: Invalid token.
Upvotes: 0
Views: 47
Reputation: 164952
localStorage.setItem('userToken', JSON.stringify(userData.token));
You're using JSON.stringify()
to store the token but aren't using JSON.parse()
when retrieving it.
It will have embedded "
characters wrapping the actual token.
const token = "my-jwt-token";
console.log("compare");
console.log({ Authorization: `Bearer ${token}` });
console.log({ Authorization: `Bearer ${JSON.stringify(token)}` });
Considering the token is just a string, I wouldn't bother with JSON.stringify()
localStorage.setItem('userToken', userData.token);
Upvotes: 1