【问题标题】:Authentication logic for sessions that last while tab is open在选项卡打开时持续的会话的身份验证逻辑
【发布时间】:2016-10-30 17:47:52
【问题描述】:

假设您正在开发通过 3rd 方 api 执行身份验证的前端应用程序。成功的身份验证会返回一个 json Web 令牌。

当用户在网站上处于活动状态(即没有关闭选项卡或浏览器)时,存储此类令牌并为用户创建某种会话的最佳做法是什么,但刷新/重新加载页面不应破坏此类会话。

另外,如何使用这个会话来保护路由?我正在使用一个由 react / redux / node / express 和其他一些库组成的堆栈。我相信我可以在我的 react-router 中执行某些检查,但是在 express 端执行这些检查不是更好吗?

【问题讨论】:

    标签: javascript node.js session express reactjs


    【解决方案1】:

    您可以将令牌存储在localStoragesessionStorage 中,并将其包含在每个 API 请求中。

    Local storage 比选项卡的寿命更长,它存储在那里,直到您明确地从中删除,因此刷新页面不会有问题。即使关闭标签然后再回来也不会。

    Session storage 允许您存储数据。页面刷新很好,但标签关闭不是,这更接近你想要的行为。

    至于保护路由,服务器显然应该检查对所有受保护 API 路由的请求的令牌。

    在浏览器端,如果用户尝试访问受保护的路由但令牌不存在(或无效),您可能希望显示登录表单。

    使用 react-router,您可以像示例中的官方 repo 所示那样,通过onEnter hooks: https://github.com/reactjs/react-router/blob/master/examples/auth-flow/app.js

    另一种方法是创建两个顶级组件,一个用于受保护的路线,一个用于公共路线(例如登录页面或登录/注册表单)。然后,受保护的处理程序将在componentWillMount 检查是否有令牌:

    - PublicHandler 
      + SignIn
      + SignUp
      + Index
    
    - ProtectedHandler
      + Dashboard
      + MoneyWithdrawal
    

    【讨论】:

    • 我刚想到一个想法,说如果有人用随机字符串设置会话,他们将获得对/dashboard 的访问权限,显然他们不会在那里看到任何数据,因为随机字符串是不是有效的令牌,但仍然可以访问受限路线
    • 但是没有后台就无法使用。您可以做的是,最初使用令牌调用服务器以查看它是否有效。如果是 - 一切正常,如果不是,则重定向到登录表单。
    【解决方案2】:

    它可能看起来像这样,带有 sessionStorageJWT 令牌是可访问的,直到浏览器或选项卡关闭)

    ///action creator redux
    export const signupUser = creds => dispatch =>{
        dispatch(requestSignup());
    
        return API.auth.signup(creds)
        .then(res =>  {
            sessionStorage.setItem('token', res.token);// <------------------
            dispatch(receiveSignup(res));
            return res;
        })
        .catch(err => {
                dispatch(SignupError(err));
             );
         });
    
    };
    

    在客户端:通过 HOC redux-auth-wrapper处理身份验证

    在服务器上在服务器上你可以使用passport-jwt策略

    passport.use('jwt',new JwtStrategy(opts, function(jwt_payload, done) {
            User.findOne({where:{ id: jwt_payload.user.id }}).then(user=>{
                if (user) {
                    done(null, jwt_payload.user);
                } else {
                    done(null, false);
                    // or you could create a new account
                }
            },err=>{
                console.log('Error ',err);
                return done(err,false);
            });
    
        }));
    

    然后只需添加路由处理程序

    var checkJWT = passport.authenticate('jwt')
    
    router.get('/protected',checkJWT, (req, res) =>{
        res.json(req.user);
    });
    

    您不需要服务器上的会话

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2016-10-16
      • 2017-10-05
      • 1970-01-01
      相关资源
      最近更新 更多