koa 护照 oauth2 将令牌保存到状态

koa passport oauth2 save token to state

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

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

Koa / passport 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;
};

应该设置和读取访问令牌的路由声明:

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的方法?

我也有同样恼人的经历。 有用的是删除 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;

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

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

我可以在本地代理这个,一切都很好!