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

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

问题描述

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

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.

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未连接到数据库,因此我可以进行查询,例如检查用户是否会话中的会话是有效的,并且具有成功登录后得到的响应中的作用.

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. 通过端口3001上的远程API登录客户端Web应用程序(已实现)
  2. 获取用户令牌和其他信息(上面显示的响应)(已实现)
  3. 确保在客户端Web应用程序上对用户进行身份验证,并且还记住登录用户的角色,以便使用这些信息对客户端应用程序上的每个路由进行授权.在客户端应用程序中,我只有几个页面,这些页面带有用于将数据发送到端口 3002 上的服务器端API的表单,这些页面供具有角色 editor 和<的两个不同用户使用em> admin .
  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天全站免登陆