【问题标题】:SailsJS v1.0 Bearer auth (API token)SailsJS v1.0 承载认证(API 令牌)
【发布时间】:2019-06-27 10:31:12
【问题描述】:

首先,这不是重复的,因为所有文档/答案都是针对 v1.0 之前的版本,它们似乎不起作用。

我正在尝试使用 passport 和 SailsJS v1.0 实现简单的身份验证。

问题是......因为我是新手,而且sailsjs (v1) 似乎缺乏在线示例,所以我很困惑。

应用程序应该像这样工作 -> 用户注册,验证他们的电子邮件,然后登录。登录后,用户会返回一个accessToken,他需要使用它来请求受保护的路线(通过Bearer 或别的东西)。

令牌应保存在数据库中,以便在用户更改密码等时使它们无效。

我怎样才能实现这样的目标?这就是我到目前为止所得到的(在线合并较旧/较新的示例)。

User.js(模型)

const bcrypt = require('bcryptjs');

module.exports = {
  attributes: {
    email: {
      type: 'string',
      required: true,
      unique: true
    },
    username: {
      type: 'string',
      required: true,
      unique: true
    },
    password: {
      type: 'string',
      required: true
    },
    tokens: {
      collection: 'token',
      via: 'userId'
    }
  },
  customToJSON: function () {
    return _.omit(this, ['password'])
  },
  beforeCreate: function (user, cb) {
    bcrypt.genSalt(10, function (err, salt) {
      bcrypt.hash(user.password, salt, null, function (err, hash) {
        if (err) return cb(err);
        user.password = hash;
        return cb();
      });
    });
  }
};

Token.js(模型)

module.exports = {

  attributes: {
    token: {
      type: 'string',
      required: true,
      unique: true
    },
    userId: {
      mode: 'user'
    },
    isValid: {
      type: 'bool',
    }
  },
};

由于我对节点非常陌生,尤其是风帆,我有很多问题。

  1. 如果数据库中的令牌是 无效(或者我应该在注册/更改时只使用 1 个令牌 密码?)
  2. 如何实现实际的身份验证过程 使用passport
  3. 令牌是否应为特定格式(字符数等) 安全原因?
  4. 是否有更好的方法来实现我想要实现的目标? (成为 更确切地说,我想要一个 REST Api 后端来为我的 ReactJS 前端提供服务 能够为 android/ios 等重用相同的后端)。

任何提示、链接、建议等将不胜感激。感谢并怜悯我缺乏知识!

编辑:这种方法会阻止我使用社交媒体登录(我也想在未来实现)?

【问题讨论】:

    标签: node.js rest sails.js passport.js bearer-token


    【解决方案1】:

    您可以使用 JWT 进行身份验证。

    使用以下代码在 api/policies 文件夹中创建名为 isAuthenticated.js 的文件。

    const passport = require('passport');
    
    module.exports = async (req, res, proceed) => {
      passport.authenticate('jwt', { session: false }, (err, user, info) => {
        if (err) {
          res.serverError(err, err.message);
        }
        if (user) {
          req.user = user;
          return proceed();
        }
        if (info) {
          return res.forbidden(info);
        }
        // Otherwise, this request did not come from a logged-in user.
        return res.forbidden();
      })(req, res, proceed);
    };
    

    使用 jwt.js 文件和以下代码在 api 文件夹中创建策略文件夹。

    const JwtStrategy = require('passport-jwt').Strategy;
    const { ExtractJwt } = require('passport-jwt');
    const passport = require('passport');
    
    const opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
    opts.secretOrKey = JWT_SECRET;
    opts.issuer = JWT_ISSUER;
    opts.audience = JWT_AUDIENCE;
    opts.jsonWebTokenOptions = {
      expiresIn: JWT_EXPIRES_IN,
    };
    
    module.exports = {
      /**
       * Passport Strategy
       */
      passport: () => {
        passport.use(new JwtStrategy(opts, (jwtPayload, done) => {
          User.findOne({ id: jwtPayload.id }, (err, user) => {
            if (err) {
              return done(err, null);
            }
            if (user) {
              return done(null, user);
            }
            return done({ message: 'No user account found' }, 'No user account found');
          });
        }));
      },
    };
    

    在 app.js require('./api/strategies/jwt').passport(); 文件的顶部。

    现在您可以将策略应用于 config/policies.js 中的路由。

    要生成JWT,可以使用以下代码。

    const jwt = require('jsonwebtoken');
    
    module.exports = {
      generate: (id, email) => jwt.sign({ id, email }, jwtSecret, {
        audience: jwtAudience,
        expiresIn: jwtExpiresIn,
        issuer: jwtIssuer,
      })
    };
    

    【讨论】:

    • 谢谢,但我宁愿使用存储在数据库中的令牌,我可以在我想要的任何时候使其失效。使用 JWT 不会让我使令牌失效,以防万一......假设用户更改了他的密码或类似的东西。
    • 在这种情况下,最好使用基于会话的身份验证。
    • 我的sailsjs 应用程序的整个想法是拥有一个rest api 后端并在React 中构建我的前端,然后在React Native 中添加移动应用程序。这就是为什么我试图将我的后端保持为独立而不是 MVC。
    猜你喜欢
    • 2014-10-11
    • 2014-12-18
    • 2020-04-07
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多