シングル サインオン システムを実装するにはどうすればよいですか?次の記事では、node を使用してシングル サインオン システムを実装する方法を紹介します。
シングルサインオン SSO(シングルサインオン)とは、複数の業務システムからログイン機能を分離して新たなシステムを構築することで、次のような効果を実現します。一度ログインすれば業務システムにログインする必要はありません。
ソース = プロトコルドメイン名ポート
http://www.a.com を例に挙げます:
同一生成元ポリシーのブラウジング アプリケーション配下のリソースにこのアプリケーションのみがアクセスできるようにすることでセキュリティを確保するサーバーの動作。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル ]
http プロトコルは であるため、なし ステータス プロトコル (クライアントとサーバー間のデータ交換が完了すると、接続は閉じられ、次回リクエストが行われたときに接続が再確立されます)、ただし、次のような機能を実行する必要がある場合パスワードを覚えているので、セッションを記録する必要があることは明らかです。
一般的に使用されるセッション トラッキングは Cookie とセッションです。簡単に理解すると、これらはキーと値を格納できるデータ構造です。違いは、Cookie がクライアント側に格納され、セッションがサーバー側に格納されることです。 。
同じ親ドメイン (例: www.app1.aaa.com
、www.app2.aaa.com
これら 2 つのサーバーは、.aaa.com の親ドメイン名です。
デフォルトでは、2 つのサーバー上のページ間の Cookie は相互にアクセスできません。
しかし、Cookie のドメイン属性を共通の親ドメイン名に設定して、2 つのサーバー上のページ間の Cookie に相互にアクセスできるようにすることができます。
router.get('/createCookie', async (ctx, next) => { ctx.cookies.set('username', '123', { maxAge: 60 * 60 * 1000, httpOnly: false, path: '/', domain:'.a.com' //设置domain为共通的父域名 }); ctx.body = "create cookie ok"})router.get('/getCookie', async (ctx, next) => { let username=ctx.cookies.get('username') if (username){ ctx.body=username }else{ ctx.body='no cookie' }})
ドメイン名が www の場合。 .com
、www.b.com
、どのようにドメインを設定しても役に立ちません。
次に、すべてのドメインの Cookie に ID 資格情報 (トークン) を書き込む方法を見つける必要があります。
<script> $.ajax({ url: 'https://www.c.com:3000/sso?key=username&value=123', method: 'get', }) </script>
<script></script>
$.ajax({ url: 'https://www.c.com:3000/sso?key=username&value=123', method: 'get', dataType:'jsonp' })
に書き込まれます。 バックエンド
const options = { key: fs.readFileSync(path.join(__dirname, './https/privatekey.pem')), cert: fs.readFileSync(path.join(__dirname, './https/certificate.pem')), secureOptions: 'TLSv1_2_method' //force TLS version 1.2}var server = https.createServer(options,app.callback()); //只能使用https协议写cookierouter.get('/sso', async (ctx, next) => { let { key, value } = ctx.request.query ctx.cookies.set(key, value, { maxAge: 60 * 60 * 1000, //有效时间,单位毫秒 httpOnly: false, //表示 cookie 是否仅通过 HTTP(S) 发送,, 且不提供给客户端 JavaScript (默认为 true). path: '/', sameSite: 'none', //限制第三方 Cookie secure: true //cookie是否仅通过 HTTPS 发送 }); ctx.body = 'create Cookie ok'})
注:
彼の設定した Cookie はhttp-only のためブロックされました http-only: Cookie が HTTP(S) 経由でのみ送信され、クライアント JavaScript に提供されないかどうかを示します (デフォルトは true)。
したがって、httpOnly を false に設定します。 .
この set-Cookie はユーザー設定によりブロックされました これは本当に落とし穴です。ブラウザをシークレット モードで開きました。ただし、Chrome ブラウザではデフォルトでシークレット モードのサードパーティ Cookie が無効になっています。すべての Cookie を許可するように変更してください。
SameSite 属性があるが Secure が設定されていないため、この設定された Cookie はブロックされました SameSite 属性と Secure 属性を設定する必要があります
これは、Cookie を書き込むための koa フレームワークの制限だと思います。 https による Cookie の書き込みのみをサポートできるため、www.c.com を https サーバーに変更しました。ドメイン
router.get('/sso', async (ctx, next) => { let { key, value } = ctx.request.query ctx.cookies.set(key, value, { maxAge: 60 * 60 * 1000, //有效时间,单位毫秒 httpOnly: false, path: '/', sameSite: 'none', secure: true }); ctx.set("P3P", "CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'") //p3p响应头 ctx.body = 'create Cookie ok'})
访问http://www.c.com:3000/createToken?from=http://www.a.com/createCookie
www.c.com上生成token后将url重写,带上token,重定向到www.a.com
router.get('/createToken', async (ctx, next) => { let { from } = ctx.request.query let token = "123"; ctx.response.redirect(`${from}?token=${token}`)})
www.a.com上从url上获取token,存入cookie
router.get('/createCookie', async (ctx, next) => { let { token } = ctx.request.query ctx.cookies.set('token', token, { maxAge: 60 * 60 * 1000, //有效时间,单位毫秒 httpOnly: false, path: '/', }); ctx.body = 'set cookie ok'})
这样就实现了跨域信息的传递.与上面的方式不同,这种方法只是单纯的http请求,适用于所有浏览器,但是缺点也很明显,每次只能分享给一个服务器。
之前2.1.1利用标签在www.a.com中写入了www.c.com的cookie(username,123),现在想要www.a.com请求的时候携带上www.c.com的cookie,也就是说要跨域读cookie.
其实也是同样的方法,在www.a.com上利用跨域访问访问www.c.com,会自动的带上domain为www.c.com的cookie。www.a.com/index.js
<script></script>
www.c.com
router.get('/readCookie', async (ctx, next) => { let username = ctx.cookies.get('username') console.log('cookie', username)})
可以看到读取到了存储在www.a.com里面domain为www.c.com的cookie.
效果如图所示:
第一次访问www.a.com首页
跳转到www.c.com:3000登录页面,登录成功后跳转www.a.com首页
再次访问www.a.com首页,无需登录直接跳转
访问www.b.com首页,无需登录直接跳转
源码: https://github.com/wantao666/sso-nodejs
详细设计:
更多node相关知识,请访问:nodejs 教程!
以上がノードがシングル サインオン システムを実装する方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。