如何进行身份验证使用使用 Passport.js 的远程 NodeJS API 授权客户端 Web 应用程序 [英] How to Authenticate & Authorize a Client-Side Web App using Remote NodeJS API that uses Passport.js

查看:25
本文介绍了如何进行身份验证使用使用 Passport.js 的远程 NodeJS API 授权客户端 Web 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如下图所示,我在端口为 3001 的服务器上运行了一个独立的 API 项目,在端口为 3002 的服务器上运行了一个 Web 应用程序.

As shown in the illustration below, I have a standalone API Project running on a server with a port say 3001, and I have a Web App running on a server with port say 3002.

端口 3001 上的 API,具有 Web 应用(和移动应用)获取和放置数据所需的所有 API 路由,包括身份验证 API(使用 passport-localpassport-jwt).在项目的 API 端,我也处理了用户角色授权,每个路由都有可以访问 API 的角色列表.

API on port 3001, has all the API routes required for the Web App (& mobile apps) to fetch and put data, including Authentication API (Using passport-local and passport-jwt). In the API side of the project, I have also handled user role authorization, and every routes has list of roles who can access the APIs.

示例路线

todoRoutes.get('/', 
               requireAuth,
               AuthController.roleAuth(['user','editor','admin']),
               TodoController.getTodos);

3001端口的角色授权API方法

exports.roleAuth = function(roles){

    return function(req, res, next){

        var user = req.user;

        User.findById(user._id, function(err, foundUser){

            if(err){
                res.status(422).json({error: 'No user found.'});
                return next(err);
            }

            if(roles.indexOf(foundUser.role) > -1){
                return next();
            }

            res.status(401).json({error: 'You are not authorized to view this content'});
            return next('Unauthorized');

        });
    }
}

登录成功后的响应json是这样的

{
    "token": "JWT eyJhbGci...",
    "user": {
        "_id": "5986b81d940bab06ddc79b34",
        "email": "myemail@gmail.com",
        "role": "admin"
    }
}

现在在Web App中,我想使用相同的角色授权和身份验证(登录),但是你看,Web App没有连接到数据库,让我进行查询,例如检查用户在 session 中是有效的,并且具有在登录成功后得到的响应中的作用.

Now in Web App, I want to use same role authorization and authentication (login), but you see, Web App is not connected to database, for me to make queries like check if the user in session is valid and has the role as in the response it got after login successfully.

总结以下是我在这个问题中寻找的要点:

Summary Here are bullet points of what I was looking for in this question:

  1. 通过远程 API 在端口 3001 上登录客户端 Web 应用程序(已实现)
  2. 获取用户令牌和其他信息(上面显示的响应)(已实现)
  3. 确保用户在客户端 Web 应用上通过身份验证,并记住登录用户的角色,以使用这些信息对客户端应用上的每个路由进行授权.在客户端应用程序中,我有几个带有表单的页面,可以在端口 3002 上将数据发送到服务器端 API,这些页面由两个具有 editor 角色的不同用户使用em>管理员.
  1. Login on Client-Side Web Application, via Remote API on port 3001 (achieved)
  2. Get User Token and other information (response shown above) (achieved)
  3. Ensure user is authenticated on Client-Side Web App and also remember role of the user loggedin, to use these information for authorization of every routes on Client-side app. In client-side app I have few pages with forms to send data to Server-Side API on port 3002, these pages are used by two different user with roles editor and admin.

TIA

推荐答案

您的身份验证 API 应该返回一个带有保证信息(角色)的 JWT.此外,应使用您的视图 API 已知的秘密来制作令牌.

Your authenticating API should return a JWT with guaranteed information (the role) embedded. Further, the token should be made using a secret known to your view APIs.

例如,使用 npm 模块 jsonwebtoken,像这样签名:

For example, using npm module jsonwebtoken, sign it like so:

token = jwt.sign( {
    exp: Math.floor( Date.now() / 1000 ) + ( 60 * 60 ), // 1 hour
    i: user._id,
    role: user.role
}, "my-secret" );

然后,在您的视图 API 上,使用 passport-jwt,这两者都会验证令牌并为您提供与您签名的原始对象匹配的有效负载.使用负载作为用户对象:

Then, on your view API, use passport-jwt, which both verifies the token and provides you a payload that matches the original object you signed. Use the payload as the user object:

passport.use( new JwtStrategy( {
    secretOrKey: "my-secret"

}, ( payload, callback ) => callback( null, payload ) ) );

const authenticate = () =>
    passport.authenticate( "jwt", { session: false, failWithError: true } )

在此阶段,您的用户至少已通过身份验证.如果您想将视图限制为某些角色,您可以添加第二个中间件:

At this stage, your user is at minimum authenticated. If you want to restrict a view to certain roles, you would add a second middleware:

const assertRole = ( ...roles ) => ( req, res, next ) => 
    req.user && roles.includes( req.user.role ) ? next() : res.sendStatus( 403 ) );

todoRoutes.get("/admin/view1", authenticate, assertRole( "user", "editor", "admin" ), TodoController.getTodos );

如果您的视图需要有关用户的更多信息,则身份验证 API 将需要在 JWT 中(因此有保证)或外部(不保证,但会生成较小的令牌)提供这些信息.

If your view is going to be need more information about the user, the authentication API will need to provide that, either in the JWT (and thus guaranteed) or outside (not guaranteed, but results in smaller tokens).

这篇关于如何进行身份验证使用使用 Passport.js 的远程 NodeJS API 授权客户端 Web 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆