Heim > Web-Frontend > js-Tutorial > Hauptteil

Was ist Single Sign-On? So implementieren Sie SSO mit Nodejs

青灯夜游
Freigeben: 2022-06-10 20:31:02
nach vorne
4352 Leute haben es durchsucht

Was ist Single Sign-On? Der folgende Artikel führt Sie in das Prinzip des Single Sign-On ein und erläutert die Methode zur Verwendung von Node zur Implementierung von Single Sign-On SSO. Ich hoffe, er wird Ihnen hilfreich sein!

Was ist Single Sign-On? So implementieren Sie SSO mit Nodejs

Was ist Single Sign-On?

Mit zunehmendem Geschäftsvolumen des Unternehmens werden zwangsläufig unterschiedliche Systeme generiert. Es ist sehr unpraktisch, wenn für jedes System eine separate Anmeldung erforderlich ist.

So entstand eine Lösung wie Single Sign-On. Der vollständige Name von Single Sign-On lautet Single Sign On, kurz SSO. Dies bedeutet, dass Sie sich bei einem System in mehreren Systemanwendungsgruppen anmelden können in allen anderen Systemen ohne erneute Anmeldung autorisiert werden.

Zum Beispiel hat sich Xiao Ming heute bei Taobao angemeldet, er wird aufgefordert, Authentifizierungsinformationen (Benutzername, Passwort usw.) einzugeben, wenn er die Seite von Tmall besucht direkt ohne Anmeldung.

Prinzip des Single Sign-On

Was ist Single Sign-On? So implementieren Sie SSO mit Nodejs

SSO erfordert eine unabhängige Zertifizierungsstelle, die den Benutzernamen, das Passwort und andere Sicherheitsinformationen des Benutzers akzeptieren kann die der Zertifizierungsstelle. Der gesamte Vorgang kann einfach mit dem Bild oben beschrieben werden:

  • Wenn sich der Benutzer anmeldet, um auf Anwendung A zuzugreifen, stellt Anwendung A fest, dass der Benutzer nicht angemeldet ist, springt zum SSO-Authentifizierungscenter und verwendet seine eigene Adresse als ein Parameter zur Erleichterung von Rückrufen

  • SSO Das Authentifizierungscenter stellt fest, dass sich der Benutzer noch nicht angemeldet hat, und leitet den Benutzer zur Anmeldeseite weiter. Der Benutzer gibt den Benutzernamen und das Kennwort ein, um einen Anmeldeantrag einzureichen Erstellen Sie die Benutzerinformationen und erstellen Sie eine Sitzung zwischen dem Benutzer und dem SSO-Authentifizierungszentrum (die Informationen werden zu diesem Zeitpunkt in einem Cookie gespeichert) und erstellen Sie gleichzeitig ein Autorisierungstoken. Das SSO-Zertifizierungszentrum springt zur ursprünglichen Anfrage Adresse (Anwendung A) mit dem Token

  • Anwendung A erhält das Token und geht zum SSO-Zertifizierungszentrum, um zu überprüfen, ob es gültig ist. Wenn es zurückgegeben wird, registrieren Sie Anwendung A effektiv.

  • Anwendung A erstellt eine Sitzung mit dem Benutzer, zeigt Ressourcen an und behält den Anmeldestatus des Benutzers bei

  • Wenn der Benutzer auf Anwendung B zugreift, wird festgestellt, dass der Benutzer nicht angemeldet ist (der SSO-Authentifizierungsserver und Anwendung A und Anwendung B sind nicht dieselbe Domäne und können den Anmeldestatus nicht bereitstellen ), springen Sie zum SSO-Zertifizierungszentrum und bringen Sie Ihre Adress- und Cookie-Informationen aus der vorherigen Sitzung mit dem SSO-Zertifizierungszentrum mit

  • Das SSO-Zertifizierungszentrum stellt fest, dass der Benutzer angemeldet ist und springt zurück zur Anwendungs-B-Adresse und Hängen Sie das Token-Token an

  • Die gleiche Anwendung B erhält das Token und geht zum SSO-Zertifizierungszentrum, um zu überprüfen, ob es gültig ist. Wenn es eine gültige registrierte Anwendung B zurückgibt, erstellt Anwendung B eine Sitzung mit dem Benutzer und zeigt Ressourcen an und behält den Benutzeranmeldestatus bei

  • NodeJS-Demonstration
  • Drei verschiedene Dienste

Hier müssen wir drei Dienste starten, um Anwendung A, SSO-Authentifizierungsserver bzw. Anwendung B zu simulieren

Der Dienst mit der Portnummer 8383 ist hier der SSO-Authentifizierungsserver, und der Rest: 8686 und :8787 repräsentieren Anwendung A bzw. Anwendung B.

Tatsächlich sind die Codes von Anwendung A und Anwendung B fast gleich. Wie in der Abbildung oben gezeigt, können wir durch Übergabe von Parametern unterschiedliche Ports und Anwendungsnamen festlegen. Schauen wir uns zunächst den Effekt an
const Koa=require('koa');
const Router=require('koa-router')
const views=require('koa-views')
const static=require('koa-static')
const path=require('path');
const app=new Koa();
const router=new Router();
const session=require('koa-session')
const koa2Req=require('koa2-request');

//模版引擎相关配置
app.use(views(path.join(__dirname,'./views')),{
    extension:'ejs'
  })
app.keys=['key']

const keyMap={
  '8686':'koa:sess8686',
  '8787':'koa:sess8787'
}
const CONFIG={
    key:keyMap[process.env.PORT] || 'koa:sess',
    maxAge:1000*60*60*24,
    httpOnly:true
}
app.use(session(CONFIG,app))

const system=process.env.SERVER_NAME
router.get("/",async (ctx)=>{
    //通过 session来判断 应用A的登录状态
    let user=ctx.session.user
    if(user){
     //...
    }
    else //1、当用户登录访问应用A时,应用A发现用户未登录(应为服务器没有保存对应的session)
    {
      let token=ctx.query.token
      //第一次登录url上也不会有令牌
      if(!token)
      {
      //1、跳转到SSO认证服务器
       ctx.redirect(`http://localhost:8383/login?redirectUrl=${ctx.host+ctx.originalUrl}`)
      }
      else
      {
        //...
      }
    }
})
app.use(router.routes())


const port=process.env.PORT||8888

app.listen(port,()=>{
    console.log(`app ${system} running at ${port}`)

})
Nach dem Login kopieren

Authentifizierungsserver zur Bestimmung des Anmeldestatus, Rendern der Anmeldeseite

Was ist Single Sign-On? So implementieren Sie SSO mit Nodejs

Authentifizierungsserver SSO

Die Verzeichnisstruktur des Authentifizierungsservers ist wie folgt Es übernimmt hauptsächlich zwei Funktionen, eine ist die Anmeldelogik und die andere ist die anschließende Überprüfung der Gültigkeit des Tokens, die durch Weiterleiten von login.js bzw. check-token.js erledigt werden

Auth/Index. js Token erstellenWas ist Single Sign-On? So implementieren Sie SSO mit Nodejs

Auth /routes/login.js

const Koa=require('koa');
const Router=require('koa-router')
const views=require('koa-views')
const path=require('path');
const app=new Koa();
const router=new Router();
const login=require("./routes/login")
const checkToken=require('./routes/check-token')
const bodyparser=require('koa-bodyparser')

app.use(views(path.join(__dirname,'./views')),{
    extension:'ejs'
  })
app.use(bodyparser())
//处理登录相关的逻辑
router.use('/login',login.routes())
//处理令牌验证的逻辑
router.use('/check_token',checkToken.routes())
app.use(router.routes())

app.listen(8383,()=>{
    console.log(`app listen at 8383`)
})
Nach dem Login kopieren
trägt das Token vom Authentifizierungsserver und springt zurück zu Anwendung A

Token-Überprüfung gibt Ressourcen zurück

Anwendung A

const service = require("../service");
const router=require("koa-router")()


router.get('/',async (ctx)=>{
  const cookies=ctx.cookies;
  const token=cookies.get('token');
  //从cookie中判断应用A的登录态
  if(token && service.isTokenVailid(token)){
    //。。。如果有登录过
  }else{
    //2、SSO认证中心发现用户没有登录过,于是渲染登录页面登录页面;
    await ctx.render('login.ejs',{
        extension:'ejs'
     })
  }
})

//。。。
module.exports=router
Nach dem Login kopieren
verarbeitet die Überprüfung Token im entsprechenden SSO Die Logik der Karte

Auth/routes/check-token

<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>统一登录</title>
</head>
<body>
    <h1>统一登录</h1>
    <form method="post">
       <div>用户名: <input type="text" name="name"/></div>
       <div>密码  <input type="text" name="password" /></div>
       <div><input type="submit" value=&#39;登录&#39;></div>
    </form>
</body>
</html>
Nach dem Login kopieren

Auth/service/index.js

router.post(&#39;/&#39;,async (ctx)=>{
//2、用户填写用户名密码提交登录申请;
   const body=ctx.request.body;
   const {name,password}=body;
    //2、SSO认证中心校验用户信息,
   if(name==="admin" && password==="123456"){
    //2、创建用户雨SSO认证中心的会话(这时会把信息保存到cookie中),同时创建授权令牌token
       const token="passport";
       await ctx.cookies.set(&#39;token&#39;,token,{
           maxAge:1000*60*60*24*30,
           httpOnly:true
       })
       if(ctx.query.redirectUrl){
       //3、sso认证中心带着令牌跳转到最初的请求地址(应用A)
           ctx.redirect(`${ctx.protocol}://${ctx.query.redirectUrl}?token=${token}`)
           //回跳地址是 http://localhost:8686/?token=passport
       }else{
           ctx.body="<h1>登录成功!</h1>"
       }
   }else{
       ctx.response.body={
           error:1,
           msg:&#39;用户名或密码错误&#39;
       }
   }
})
Nach dem Login kopieren

An diesem Punkt kann der Benutzer normal auf Anwendung A und die Anmeldeinformationen des Benutzers zugreifen ist auf dem SSO-Server und dem Anwendungs-A-Server verfügbar.

Was ist Single Sign-On? So implementieren Sie SSO mit Nodejs

Besuchen Sie Anwendung B

http://localhost:8383/login?redirectUrl=localhost:8686

Springen Sie mit Cookie zum SSO-Authentifizierungsserver

Anwendung B

//...

router.get("/",async (ctx)=>{
    let user=ctx.session.user
    if(user){
      //...
    }else{
      let token=ctx.query.token
      //...
      if(!token)
      {
      //同样既没有session也没有令牌,跳转到SSO认证服务器
      //6、当用户访问应用B时,发现用户未登录(SSO认证服务器与应用A应用B不是同一个域,不能提供登录态),跳转到SSO认证中心,并将自己的地址和之前和SSO认证中心会话的cookie信息带入
          ctx.redirect(`http://localhost:8383/login?redirectUrl=${ctx.host+ctx.originalUrl}`)
      }
      else
      {
        //。。。验证令牌的部分
      }
    }
})
app.use(router.routes())

const port=process.env.PORT||8888

app.listen(port,()=>{
    console.log(`app ${system} running at ${port}`)

})
Nach dem Login kopieren

从认证服务器携带令牌跳转回应用B

SSO认证服务器 ,再次登录时携带了cookie,因此不会再请求登录页面 Auth/routes/login

//...
router.get(&#39;/&#39;,async (ctx)=>{
  const cookies=ctx.cookies;
  const token=cookies.get(&#39;token&#39;);
  //7. SSO认证中心发现用户已登录,跳转回应用B地址,并附上令牌token
  if(token && service.isTokenVailid(token)){
    const redirectUrl=ctx.query.redirectUrl;
    if(redirectUrl){
       //带着令牌跳转回应用B
        ctx.redirect(`${ctx.protocol}://${redirectUrl}?token=${token}`)
    }else{
        ctx.body="<h1>登录成功!</h1>"
    }
  }else{
    //...渲染登录页面
  }
})
//..
Nach dem Login kopieren

令牌校验 返回资源

这里的逻辑和5,6两步一样,因为token容易伪造,所以要检验真伪。 应用B

app.use(views(path.join(__dirname,&#39;./views&#39;)),{
    extension:&#39;ejs&#39;
  })

//...

const system=process.env.SERVER_NAME
router.get("/",async (ctx)=>{
    let user=ctx.session.user
    if(user){
      //...
    }
    else
    //这时应用B依旧没有登录态 但url上有了令牌 http://localhost:8787/?token=passport
   {
      let token=ctx.query.token
      if(!token)
      {
        //...跳转去SSO登录页面
      }
      else 
      //跳回应用B时走这里的逻辑
      {
        //ajax请求 8. 同样的应用B拿到令牌去SSO认证中心认证是否有效,如果返回有效注册应用B
        const url=`://localhost:8383/check_token?token=${token}&t=${new Date().getTime()}`
        let data = await koa2Req(ctx.protocol + url);
        if(data && data.body){
            try {
                const body=JSON.parse(data.body)
                const {error,userId}=body;
                // console.log(error,userId) 0,admin
                if(error==0){
                    if(!userId){
                        ctx.redirect(`http://localhost:8383/login?redirectUrl=${ctx.host+ctx.originalUrl}`)
                        return
                    }
                    //验证通过后注册session,渲染页面
                    //9. 应用B创建与用户之间的会话,展示资源并维持用户登录态
                    ctx.session.user=userId;
                    await ctx.render(&#39;index.ejs&#39;,{
                        user:userId,
                        system
                    })
                }else{
                    ctx.redirect(`http://localhost:8383/login?redirectUrl=${ctx.host+ctx.originalUrl}`)
                }
            } catch (error) {console.log(error)}

            
        }
      }
    }
})
app.use(router.routes())

const port=process.env.PORT||8888

app.listen(port,()=>{
    console.log(`app ${system} running at ${port}`)

})
Nach dem Login kopieren

至此单点登录的大部分逻辑都已经完成,之后再session有效期内再访问页面,就不需要再登录,直接返回资源

router.get("/",async (ctx)=>{
//如果session中有用户信息,说明已经登录过,直接返回请求资源
    let user=ctx.session.user
    if(user){
        await ctx.render(&#39;index.ejs&#39;,{
              user,
              system
        })
    }
    //...
 })
Nach dem Login kopieren

原文地址:https://juejin.cn/post/7088343138905325582

作者:YoYo君

更多node相关知识,请访问:nodejs 教程

Das obige ist der detaillierte Inhalt vonWas ist Single Sign-On? So implementieren Sie SSO mit Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!