Express 集成 OIDC 单点登录指南 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lewisli1996

Express 集成 OIDC 单点登录指南

  •  
  •   lewisli1996 2020 年 9 月 11 日 643 次点击
    这是一个创建于 2051 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文以基于 Node.js 平台 Express 框架为例,以及集成 Node.js 身份认证中间件 Passport.js ,详细介绍 Express 如何集成 Authing OIDC 单点登录。

    OIDC 协议:OIDC ( OpenID Connect )是一个基于 OAuth2 协议的身份认证标准协议。OIDC 使用 OAuth2 的授权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端。

    Passport:Passport 是 Node.js 的认证中间件,特别灵活和模块化。可非常方便的植入任意基于 Express 的 Web 应用。支持用户名密码、Facebook 和 Twitter 等认证。 一、配置 Authing OIDC 应用 从 Authing.cn 注册并进入 Authing 控制台,创建 OIDC 应用,配置应用信息。

    详细配置如下: 应用名: <应用名称> 认证地址: https://<应用域名>.authing.cn 回调 URL:应用登录后回调地址,例如: http://localhost:3004/auth/cb 授权模式:默认 authorization_code 、refresh_token 、authing Token 返回类型:默认 code token 换取时认证方式:默认 client_secret_post id_token 签名算法:默认 HS256

    配置后,同时保存 OIDC 有效信息,便于后文 Express 集成使用。 App ID:5f34e94bece50b891729e345 App Secret:8226514d6740e5a9cd94fad4991e02e9 Issuer: https://aj00.authing.cn/oauth/oidc 配置信息: https://aj00.authing.cn/oauth/oidc/.well-known/openid-configuration 回调地址: http://localhost:3004/auth/cb

    二、Express 集成 Authing OIDC

    ( 1 ) Express 搭建本地服务

    const express = require('express'); var app = express(); app.listen(3004, () => console.log(Example app listening on port 3004!))

    ( 2 )连接 OIDC 应用,注册 'oidc' 策略

    const passport = require('passport'); const { Strategy, Issuer } = require('openid-client'); const cOnfig= { // oidc 配置信息 appID:'5f34e94bece50b891729e345', appSecret:'8226514d6740e5a9cd94fad4991e02e9', issuer:'https://aj00.authing.cn/oauth/oidc', configInfo:'https://aj00.authing.cn/oauth/oidc/.well-known/openid-configuration', callbackUrl:'http://localhost:3004/auth/cb' }

    (async () => { const issuer = await Issuer.discover(config.configInfo) // 连接 oidc 应用 const client = new issuer.Client({ // 初始化 issuer 信息 client_id: config.appID, client_secret: config.appSecret, id_token_signed_response_alg: 'HS256', token_endpoint_auth_method: 'client_secret_post', }); const params = { redirect_uri: config.callbackUrl, scope: 'openid profile email phone', grant_type: 'authorization_code', response_type: 'code', prompt: 'consent', } // possport 注册 oidc 策略 passport.use('oidc', new Strategy({ client, params }, (tokenset, userinfo, done) => { return done(null, userinfo); // 返回用户信息 })); })()

    ( 3 )定义 OIDC 访问、回调、用户信息查询等接口

    app.get('/auth', passport.authenticate('oidc')); app.get('/auth/cb', passport.authenticate('oidc', { successRedirect: '/', failureRedirect: '/', })); app.get('/user', (req, res) => { res.send(req.user) }) app.get('/', (req, res) => { res.send("home") })

    ( 4 )除了以上核心步骤,存储 sesssion 信息、序列化用户信息、退出等内容,请参考以下本文完整的 Express 集成 Authing OIDC 的代码文件。

    const express = require('express'); const session = require('express-session'); const passport = require('passport'); const { Strategy, Issuer } = require('openid-client'); const cOnfig= { appID:'5f34e94bece50b891729e345', appSecret:'8226514d6740e5a9cd94fad4991e02e9', issuer:'https://aj00.authing.cn/oauth/oidc', configInfo:'https://aj00.authing.cn/oauth/oidc/.well-known/openid-configuration', callbackUrl:'http://localhost:3004/auth/cb' }(async () => {

    const issuer = await Issuer.discover(config.configInfo)
    const client = new issuer.Client({ client_id: config.appID, client_secret: config. appSecret, id_token_signed_response_alg: 'HS256', token_endpoint_auth_method: 'client_secret_post', }); const params = { redirect_uri: config.callbackUrl, scope: 'openid profile email phone', grant_type: 'authorization_code', response_type: 'code', prompt: 'consent', } var app = express(); app.use(session({ secret: 'keyboard cat', resave: true, saveUninitialized: true})); app.use(passport.initialize()); app.use(passport.session()); passport.use('oidc', new Strategy({ client, params }, (tokenset, userinfo, done) => { return done(null, userinfo); }));

    app.get('/auth', passport.authenticate('oidc')); app.get('/auth/cb', passport.authenticate('oidc', { successRedirect: '/', failureRedirect: '/user', })); app.get('/user', (req, res) => { res.send(req.user) }) app.get('/', (req, res) => { res.send("home") }) app.get('/logout', (req, res) => { const logoutBaseURL = 'https://aj00.authing.cn/login/profile/logout' const appId = '5f17f5d6f64fb07b7094a41b' const logoutRedirectURL = 'http://localhost:3004' const logoutUrl = `${logoutBaseURL}?app_id=${appId}&redirect_uri=${logoutRedirectURL}` req.session.destroy(); res.redirect(logoutUrl) }) passport.serializeUser(function (user, done) { done(null, user); }); passport.deserializeUser(function (id, done) { done(null, { client_id: id }); }); app.listen(3004, () => console.log(`Example app listening on port 3004!`)) 

    })()

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1546 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 16:47 PVG 00:47 LAX 09:47 JFK 12:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86