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
});
问题:
为什么在获取 /get-token-from-state
时 ctx.state.accessToken
未定义?
我是否应该尝试像这样保留访问令牌?有没有其他途径获取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;
所以,在这里回答我自己的问题,有很多事情:
需要 - "sameSite: 'lax'"
- 会话的 Cookie 未保存在浏览器中,因为域略有偏差(端口号不同。
我可以在本地代理这个,一切都很好!
所以我正在尝试将访问令牌保存到 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
});
问题:
为什么在获取
/get-token-from-state
时ctx.state.accessToken
未定义?我是否应该尝试像这样保留访问令牌?有没有其他途径获取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;
所以,在这里回答我自己的问题,有很多事情:
-
需要
- "sameSite: 'lax'"
- 会话的 Cookie 未保存在浏览器中,因为域略有偏差(端口号不同。
我可以在本地代理这个,一切都很好!