【问题标题】:koa passport oauth2 save token to statekoa 护照 oauth2 将令牌保存到状态
【发布时间】:2020-06-27 19:06:46
【问题描述】:

所以我正在尝试将访问令牌保存到 Koa 中的状态,以供以后使用,并且不必在客户端周围传递它。

在 Koa 的 passport oauth2 documentation 之后,我正在努力坚持 ctx.state...

Koa / 护照 oauth2 设置:

server.koaApp.use(koaSession(
  {
    key: sessionKey,
    rolling: true,
    maxAge: sessionMaxAge,
    sameSite: 'none',
    secure: true,
    // @ts-ignore
    domain: undefined
  },
  server.koaApp,
));

// set up passport sessions here
function createPassport() {
  const passport = new KoaPassport();

  passport.use(new OAuth2Strategy({
    authorizationURL: oauthClientAuthUrl,
    tokenURL: oauthClientTokenUrl,
    clientID: oauthClientId,
    clientSecret: oauthClientSecret,
    callbackURL: oauthClientRedirectUrl,
  }, function(accessToken, refreshToken, params, profile, cb) {
    cb(null, {id: 'somedudesID', accessToken});
  }));

  passport.serializeUser((user, done) => {
    done(null, user);
  });

  passport.deserializeUser((user, done) => {
    done(null, user);
  });

  return passport;
};

应该设置和读取 accesstoken 的路由声明:

router.get('/authorize', passport.authenticate('oauth2'), (ctx: any) => {
        const { accessToken } = ctx.session.passport.user;
        ctx.state.accessToken = accessToken;
        ctx.status = 200;
      });

    router.get('/get-token-from-state', (ctx: any) => {
      console.log(ctx.state.accessToken); // undefined
    });

问题:

  1. 为什么在获取/get-token-from-statectx.state.accessToken 未定义?

  2. 我是否应该尝试像这样保留访问令牌?有没有其他途径获取accessToke的方法?

【问题讨论】:

    标签: node.js oauth-2.0 passport.js koa


    【解决方案1】:

    我也有同样烦人的经历。 有帮助的是删除 koa-session 并将其替换为 koa-generic-session。然后我设置了一个内存存储 -> 现在它可以工作了:)

    我不确定将令牌存储在内存会话中是否是最好的主意 - 但现在它是我的初稿。 它只是一个小代码块,可以与 keycloak 取得联系。

    server.js

        var app = new Koa();
        app.keys = ['keys', 'keykeys'];
        var memoryStore = new session.MemoryStore();
    
        // Session
        app.use(session({
            secret: 'some secret',
            resave: false,
            saveUninitialized: true,
            store: memoryStore
          }));
    
        // Passport
        const passport = require('./oauth2')
        app.use(passport.initialize());
        app.use(passport.session());

    oauth2.js

    const request = require('request');
    const passport = require('koa-passport');
    const OAuth2Strategy = require('passport-oauth2').Strategy;
    
    
    const clientId = "b2m";
    const clientSecrect = "57ce5bba-f336-417f-b9c2-06157face88f";
    
    OAuth2Strategy.prototype.userProfile = function (accessToken, done) {
      var options = {
          url: 'http://localhost:8080/auth/realms/master/protocol/openid-connect/userinfo',
          headers: {
              'User-Agent': 'request',
              'Authorization': 'Bearer ' + accessToken,
          }
      };
    
      request(options, callback);
    
      function callback(error, response, body) {
          if (error || response.statusCode !== 200) {
              return done(error);
          }
          var info = JSON.parse(body);
          return done(null, info);
      }
    };
    
    passport.use(new OAuth2Strategy({
        authorizationURL: 'http://localhost:8080/auth/realms/master/protocol/openid-connect/auth',
        tokenURL: 'http://localhost:8080/auth/realms/master/protocol/openid-connect/token',
        clientID: clientId,
        clientSecret: clientSecrect,
        callbackURL: "http://localhost:3000/callback"
      },
      function(accessToken, refreshToken, profile, cb) {
        console.log('#########################################################');
        console.log('Authenticated with OAuth2');
        console.log('accessToken', accessToken);
        console.log('refreshToken', refreshToken);
        
        var user = {
          accessToken: accessToken,
          refreshToken: refreshToken,
          profile: profile
        };
        console.log('user', user);
    
        return cb(null, user);
      }
    ));
    
    /* Example: storing user data received from the strategy callback in the session, i.e. in `req.session.passport.user` */
    passport.serializeUser(function(user, done) {
        done(null, user);
      });
      
    /* Example: getting the user data back from session and attaching it to the request object, i.e. to `req.user` */
    passport.deserializeUser(function (user, next) {
        /*
          Example: if only a user identifier is stored in the session, this is where
          the full set could be retrieved, e.g. from a database, and passed to the next step
        */
        next(null, user);
    });
    
    module.exports = passport;

    【讨论】:

    • 谢谢@Axel!我对您的方法更进一步,但仍然无法将用户从ctx.statectx.session 中拉出来。日志:ctx.state = { _passport: { instance: KoaPassport { _key: 'passport', _strategies: [Object], _serializers: [Array], _deserializers: [Array], _infoTransformers: [], _framework: [Object], _userProperty : 'user', _sm: [SessionManager] } } } ctx.session = { cookie: { httpOnly: true, path: '/', overwrite: true, signed: true, maxAge: 86400000 } }
    【解决方案2】:

    所以,在这里回答我自己的问题,有很多事情:

    1. 需要“sameSite: 'lax'”
    2. 会话的 Cookie 未保存在浏览器中,因为域略有不同(端口号不同。

    我能够在本地代理这个,一切都很好!

    【讨论】:

      猜你喜欢
      • 2019-09-13
      • 2021-05-03
      • 2019-01-06
      • 2019-05-15
      • 2020-01-14
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 2019-11-17
      相关资源
      最近更新 更多