Reputation: 820
I am using passport-jwt strategy to protect auth users in my app, once I login I am generating a jwt-token
now I want to protect my welcome page rout so that user cannot open it without login
So when I login I am creating jwt-token
with payload
like this
my user.js file
const payload = { email: rows[0].email } // jwy payload
console.log('PAYLOAD')
console.log(payload)
jwt.sign(
payload,
key.secretOrKey, { expiresIn: 3600 },
(err, token) => {
res.json({
success: true,
token: 'Bearer ' + token,
email
})
})
Now in my passport.js I am doing like this
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
let payLoadEmail = jwt_payload.email //payload data what I have passed in creating jwt
console.log("payload email :" + payLoadEmail)
User.fetchLogedInUser(payLoadEmail)
.then(([rows]) => {
if (rows.length > 0) {
return done(null, rows[0].email) // returning data what I need
}
return done(null, false)
})
.catch(err => console.log(err))
}));
Both are working fine.
Now I want to protect my welcome rout so in my router.js file
const express = require('express');
const router = express.Router();
const passport = require('passport')
const UsersCtrl = require('../controllers/users');
router.use('/login', UsersCtrl.login)
router.use('/welcome',passport.authenticate('jwt',{session:false}))
router.use('/logout', UsersCtrl.logout)
module.exports = router;
suppose user types localhost:8080/welcome
without login then I want to protect it
So in my store.js file when user logs in I am doing this on login click and I have made a method getAuthUser
. I don't know how to I pass this config to protect my welcome file
Here is my full store.js code
import axios from 'axios'
import jwt from 'jsonwebtoken'
function checkTokenValidity(token) { // token validity
if (token) {
const decodedToken = jwt.decode(token)
return decodedToken && (decodedToken.exp * 1000) > new Date().getTime()
}
return false
}
export default {
namespaced: true,
state: {
user: null,
isAuthResolved: false // this I am calling on my login page i am confused where should I call this or not to call this
},
getters: {
authUser(state) {
return state.user
},
isAuthenticated(state) {
return !!state.user
}
},
actions: {
loginWithCredentials({ commit }, userDate) {
return axios.post('/api/v1/users/login', userDate)
.then(res => {
const user = res.data
console.log(user.email)
localStorage.setItem('jwt-token', user.token)
commit('setAuthUser', user)
})
},
logout({ commit }) {
return new Promise((resolve, reject) => {
localStorage.removeItem('jwt-token')
commit('setAuthUser', null)
resolve(true)
})
},
getAuthUser({ commit, getters }) {
const authUser = getters['authUser']
const token = localStorage.getItem('jwt-token')
const isTokenValid = checkTokenValidity(token)
if (authUser && isTokenValid) {
return Promise.resolve(authUser)
}
const config = { // here what to do with this how can I pass this to protect my route
headers: {
'cache-control': 'no-cache',
'Authorization': token
}
}
}
},
mutations: {
setAuthUser(state, user) {
return state.user = user
},
setAuthState(state, authState) {
return state.isAuthResolved = authState
}
}
In my route.js vue file
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
}, ]
})
router.beforeEach((to, from, next) => {
store.dispatch('auth/getAuthUser')
.then((authUser) => {
const isAuthenticated = store.getters['auth/isAuthenticated']
if (to.meta.onlyAuthUser) {
if (isAuthenticated) {
next()
} else {
next({ name: 'PageNotAuthenticated' })
}
} else if (to.meta.onlyGuestUser) {
if (isAuthenticated) {
next({ name: 'welcome' })
} else {
next()
}
} else {
next()
}
})
})
export default router
My main problem is I want to protect routes and make the user authenticated using jwt and passport I am getting jwt once I login and want to check once my protected rout is access with out login for backend.
In front end (vue.js) I my store file in action> getAuthUsers
I don't know how to pass config to other routes like my welcome.
Upvotes: 2
Views: 3107
Reputation: 1587
Not sure if I understood your question entirely because you seem to be implementing route access correctly. You simply need to add routes as an array while the rest of your code remains the same.
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
},
{
path: '/login',
name: 'Login',
meta: { onlyGuesUser: true },
component: () =>
import ('./views/Login.vue'),
}]
})
For using Authentication: Bearer xxxxxxxx
you can modify your axios
code to directly use required headers instead of passing it through routes every time. Make a new folder called services
and a file called base-api
. You can obviously name it however you like, but this is my setup.
import axios from 'axios';
export default () => {
let headers = {
'cache-control': 'no-cache'
};
let accessToken = localStorage.getItem('jwt-token');
if (accessToken && accessToken !== '') {
headers.Authorization = accessToken;
};
return axios.create({
baseURL: 'SECRET_URL_',
headers: headers
});
}
Import this file in your store.js
. Replace import axios from 'axios'
with import axios from '@src/services/base-api.js
. As the file is returning an axios instance you need to access it as axios()
. Which means you function would be
return axios().post('/api/v1/users/login', userDate)
.then(res => {
// do whatever
})
Upvotes: 2