2017-03-15 136 views
1

我有3個工作單位,並且擁有自己的會話登錄/註銷管理。Forge 3腿Oauth - 以其他用戶/強制登出身份登錄

註銷後,如果用戶想再次登錄,我送他去 https://developer.api.autodesk.com/authentication/v1/authorize,它會直接到我的回調與已驗證的,而不是提示輸入新的登錄以前的用戶。

好像歐特克存儲會話作爲cookie如此授權之後切換用戶的唯一方法是清除瀏覽器緩存/數據

有沒有辦法強制註銷,或者類似的東西「登陸在另一個用戶「?

這是我第一次做oauth,所以我不確定我錯過了什麼,但似乎應該有辦法強制清除會話並強制一個新的登錄。


編輯

讓我進一步澄清什麼,我想實現:

這裏是我有什麼。 1.我將用戶引導到認證頁面將其引導到: https://developer.api.autodesk.com/authentication/v1/authorize?response_type=code&client_id=obQDn8P0GanGFQha4ngKKVWcxwyvFAGE&redirect_uri=http%3A%2F%2F{{mycallback}}%2Fcallback%3Ffoo%3Dbar&scope=data:read

  • 在與他的Autodesk憑證用戶登錄

  • 授權流重定向的用戶爲`mycallback.com/callback/?code={{code}}

  • 我的後端得到的是一個從URL請求的code參數,並提出了POST請求https://developer.api.autodesk.com/authentication/v1/gettoken

  • 請求返回,除其他事項外,一個access_token

  • 我存儲access_token用戶的會話,並用它來使該API的下一個請求。

  • 到目前爲止,它的工作原理與我預期的一樣。現在我想將用戶登錄出去,並可能以不同的用戶身份登錄。

    1. 我的服務器上的一個/註銷終點清除了用戶會話,從而消除了存儲的access_token。

    2. 一旦後端意識到沒有活動的會話/訪問令牌,它將用戶重定向到認證流程(上述步驟#1)。

    3. 此時,我希望看到另一個Autodesk登錄頁面,但Autodesk的服務器會自動授權而無需新的登錄名,並重定向用戶以回叫,並且用戶再次登錄。

    所以要改寫我的問題,如何改變上述#9的行爲,讓用戶必須重新輸入他的憑據?

    我在開發過程中經常遇到這種情況,我用我的個人帳戶登錄,然後登出,我想用我的工作帳戶登錄。 目前,我可以做到這一點的唯一方法就是清除瀏覽器的緩存。 這讓我想到Autodesk將會話存儲在瀏覽器中,這就是爲什麼它不需要獲取新憑證即可重新進行身份驗證。

    您的dm.autodesk.io上發生的行爲相同 第一次登錄後,如果我嘗試再次授權,我不會提示第二次登錄,而是會自動重新登錄第一個用戶I用...登錄。

    如果我明白正確發生了什麼,似乎API應該有一個端點,我們可以在用戶註銷時強制重新進行身份驗證。

    有意義嗎?

    謝謝!

    回答

    0

    我不確定你的意思是「我發送他到https://developer.api.autodesk.com/authentication/v1/authorize但這必須發生在您的服務器上。

    檢查我的示例在https://dm.autodesk.io:允許彈出窗口並單擊導航欄中的「用戶數據」。登錄後,用戶會話就會安全地存儲在服務器上。如果您重新加載頁面,它會自動登錄。如果再次單擊導航欄按鈕,它將清除服務器上的會話,如果重新加載,則不會登錄。我想這就是您正在查找的行爲。

    該項目代碼位於there。三條腿的邏輯是從there處理,如下(node.js的)看:

    import ServiceManager from '../services/SvcManager' 
    import { serverConfig as config } from 'c0nfig' 
    import { OAuth2 } from 'oauth' 
    import express from 'express' 
    
    module.exports = function() { 
    
        var router = express.Router() 
    
        /////////////////////////////////////////////////////////////////////////// 
        // 2-legged client token: exposes a 'data:read' only token to client App 
        // 
        /////////////////////////////////////////////////////////////////////////// 
        router.get('/token/2legged', async(req, res) => { 
    
        try { 
    
         var forgeSvc = ServiceManager.getService('ForgeSvc') 
    
         var token = await forgeSvc.request2LeggedToken('data:read') 
    
         res.json(token) 
    
        } catch (error) { 
    
         res.status(error.statusCode || 404) 
         res.json(error) 
        } 
        }) 
    
        ///////////////////////////////////////////////////////////////////////////// 
        // Initialize OAuth library 
        // 
        ///////////////////////////////////////////////////////////////////////////// 
    
        var oauth2 = new OAuth2(
        config.forge.oauth.clientId, 
        config.forge.oauth.clientSecret, 
        config.forge.oauth.baseUri, 
        config.forge.oauth.authorizationUri, 
        config.forge.oauth.accessTokenUri, 
        null) 
    
        ///////////////////////////////////////////////////////////////////////////// 
        // login endpoint 
        // 
        ///////////////////////////////////////////////////////////////////////////// 
        router.post('/login', function (req, res) { 
    
        var authURL = oauth2.getAuthorizeUrl({ 
         redirect_uri: config.forge.oauth.redirectUri, 
         scope: config.forge.oauth.scope.join(' ') 
        }) 
    
        res.json(authURL + '&response_type=code') 
        }) 
    
        ///////////////////////////////////////////////////////////////////////////// 
        // logout endpoint 
        // 
        ///////////////////////////////////////////////////////////////////////////// 
        router.post('/logout', (req, res) => { 
    
        var forgeSvc = ServiceManager.getService(
         'ForgeSvc') 
    
        forgeSvc.delete3LeggedToken(req.session) 
    
        res.json('success') 
        }) 
    
        ///////////////////////////////////////////////////////////////////////////// 
        // Reply looks as follow: 
        // 
        // access_token: "fk7dd21P4FAhJWl6MptumGkXIuei", 
        // refresh_token: "TSJpg3xSXxUEAtevo3lIPEmjQUxXbcqNT9AZHRKYM3", 
        // results: { 
        // token_type: "Bearer", 
        // expires_in: 86399, 
        // access_token: "fk7dd21P4FAhJWl6MptumGkXIuei" 
        // } 
        // 
        ///////////////////////////////////////////////////////////////////////////// 
        router.get('/callback/oauth', (req, res) => { 
    
        var socketSvc = ServiceManager.getService(
         'SocketSvc') 
    
        // filter out errors (access_denied, ...) 
        if (req.query && req.query.error) { 
    
         if (req.session.socketId) { 
    
         socketSvc.broadcast(
          'callback', req.query.error, 
          req.session.socketId) 
         } 
    
         res.json(req.query.error) 
         return 
        } 
    
        if(!req.query || !req.query.code) { 
    
         res.status(401) 
         res.json('invalid request') 
         return 
        } 
    
        oauth2.getOAuthAccessToken(
         req.query.code, { 
         grant_type: 'authorization_code', 
         redirect_uri: config.forge.oauth.redirectUri 
         }, 
         function (err, access_token, refresh_token, results) { 
    
         try { 
    
          var forgeSvc = ServiceManager.getService(
          'ForgeSvc') 
    
          var token = { 
          scope: config.forge.oauth.scope, 
          expires_in: results.expires_in, 
          refresh_token: refresh_token, 
          access_token: access_token 
          } 
    
          forgeSvc.set3LeggedTokenMaster(
          req.session, token) 
    
          if(req.session.socketId) { 
    
          socketSvc.broadcast(
           'callback', 
           'success', 
           req.session.socketId) 
          } 
    
          res.end('success') 
    
         } catch (ex) { 
    
          res.status(500) 
          res.end(ex) 
         } 
         } 
        ) 
        }) 
    
        ///////////////////////////////////////////////////////////////////////////// 
        // logout route 
        // 
        ///////////////////////////////////////////////////////////////////////////// 
        router.post('/logout', (req, res) => { 
    
        var forgeSvc = ServiceManager.getService(
         'ForgeSvc') 
    
        forgeSvc.logout(req.session) 
    
        res.json('success') 
        }) 
    
        /////////////////////////////////////////////////////////////////////////// 
        // 3-legged client token: exposes a 'data:read' only token to client App 
        // 
        /////////////////////////////////////////////////////////////////////////// 
        router.get('/token/3legged', async (req, res) => { 
    
        var forgeSvc = ServiceManager.getService(
         'ForgeSvc') 
    
        try { 
    
         var token = await forgeSvc.get3LeggedTokenClient(
         req.session) 
    
         res.json({ 
         expires_in: forgeSvc.getExpiry(token), 
         access_token: token.access_token, 
         scope: token.scope 
         }) 
    
        } catch (error) { 
    
         forgeSvc.logout(req.session) 
    
         res.status(error.statusCode || 404) 
         res.json(error) 
        } 
        }) 
    
        return router 
    } 
    
    +0

    嗨菲利普 - 我加了一些更多的細節,我的問題。 – gtalarico

    +0

    我明白了,是的,我認爲如果您在同一臺瀏覽器上登錄A360帳戶,它將使用會話數據。我會檢查是否有解決方法。一種解決方法是從A360註銷 –

    相關問題