如何在 Vuejs 和 Node 中设置授权标头并保护路由
Posted
技术标签:
【中文标题】如何在 Vuejs 和 Node 中设置授权标头并保护路由【英文标题】:How to set authorization header and protect routes in Vuejs and Node 【发布时间】:2020-02-14 01:35:12 【问题描述】:我正在使用 passport-jwt 策略来保护我的应用程序中的 auth 用户,一旦我登录,我就会生成一个 jwt-token
现在我想保护我的欢迎页面溃败,以便用户在没有登录的情况下无法打开它
所以当我登录时,我会像这样用payload
创建jwt-token
我的 user.js 文件
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
)
)
现在在我的 passport.js 中,我正在这样做
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))
));
两者都工作正常。
现在我想在我的 router.js 文件中保护我的欢迎路由
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;
假设用户在没有登录的情况下输入localhost:8080/welcome
,那么我想保护它
所以在我的 store.js 文件中,当用户登录时,我在登录点击时执行此操作,并且我创建了一个方法 getAuthUser
。我不知道如何通过此配置来保护我的欢迎文件
这是我完整的 store.js 代码
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
在我的 route.js vue 文件中
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
我的主要问题是我想保护路由并让用户使用 jwt 和护照进行身份验证我在登录后得到 jwt 并且想要检查我的受保护路由是否可以访问而无需登录后端。
在前端 (vue.js) 我的存储文件在运行> getAuthUsers
我不知道如何将配置传递给其他路由,比如我的欢迎。
【问题讨论】:
【参考方案1】:不确定我是否完全理解您的问题,因为您似乎正确地实现了路由访问。您只需将路由添加为数组,而其余代码保持不变。
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'),
]
)
对于使用Authentication: Bearer xxxxxxxx
,您可以修改axios
代码以直接使用所需的标头,而不是每次都通过路由传递它。创建一个名为services
的新文件夹和一个名为base-api
的文件。显然,您可以随意命名,但这是我的设置。
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
);
将此文件导入您的store.js
。将import axios from 'axios'
替换为import axios from '@src/services/base-api.js
。当文件返回一个 axios 实例时,您需要以axios()
访问它。这意味着你的功能将是
return axios().post('/api/v1/users/login', userDate)
.then(res =>
// do whatever
)
【讨论】:
嘿,base-api.jsheaders.Authorization =
Bearer $jwt-token;
代替 Bearer$jwt-token 我可以像这样简单地通过 headers.Authorization =
accessToken `因为我已经在 Bearer 前缀中获得了令牌?
是的,这完全取决于你,我添加了一个单词用于演示如何进一步编辑标题。
嘿,我应该在 base-api.js baseURL: 'SECRET_URL_',
987654335@ 中传递什么网址
嗯,你正在做axios.post('/api/v1/users/login', userDate)
,所以假设实际的网址是http://localhost:8000/api/v1/users/login
,那么你将通过http://localhost:8000/
作为基本网址。以上是关于如何在 Vuejs 和 Node 中设置授权标头并保护路由的主要内容,如果未能解决你的问题,请参考以下文章