如何在Vuejs和Node

时间:2019-10-17 07:42:11

标签: javascript node.js vue.js jwt passport.js

我正在使用password-jwt策略来保护我的应用程序中的身份验证用户,登录后,我现在会生成jwt-token,因此我想保护我的欢迎页面,以便用户无需登录就无法打开它

因此,当我登录时,我像这样用jwt-token创建payload

我的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
                    })

                })

现在在我的password.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和passport进行身份验证,一旦我登录就得到了jwt,并且想要检查我受保护的路由是否可以不登录后端登录。

在前端(vue.js)中,我的商店文件正在运行> getAuthUsers,我不知道如何将配置传递给其他路线,例如我的欢迎。

1 个答案:

答案 0 :(得分:2)

不确定您是否完全理解了您的问题,因为您似乎正确实现了路由访问。您只需要将路由添加为数组,而其余代码保持不变。

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
                })