簡體   English   中英

帶有Ionic 3和Rails的OAuth(devise_token_auth)

[英]OAuth with Ionic 3 and Rails (devise_token_auth)

我正在使用Ruby on Rails后端構建Ionic 3(Angular 4)應用程序。

我正在使用angular2-tokendevise_token_auth進行用戶和API調用身份驗證,這兩個功能可以一起使用。

它們的工作方式很簡單:它們在每個API調用標頭上創建並跟蹤一些字段(即auth-tokenclientuidexpiry )。

它可以完美地使用電子郵件注冊/登錄。 我現在想為我的應用程序實現Instagram OAuth登錄,這在常規的Angular Web應用程序中應該是InAppBrowser事,但是在Ionic中,我無法控制路由或URL,因此可以采取的策略是啟動InAppBrowser並在其上設置事件以檢測其何時到達我的API回調URL。

基本上:

  1. 我加載myapi.com/auth/instagram內部InAppBrowser
  2. Instagram登錄,重定向到回調URL
  3. InAppBrowser加載myapi.com/omniauth/instagram/callback?code=57... ,我檢測到它。

至此,我的后端已經根據Instagram數據成功創建了一個用戶。

問題是,我不知道如何在客戶端進行處理。

當我使用電子郵件/密碼登錄時, angular2-token作用是POST /auth/sign_in ,請求標頭包含auth_token和東西,然后對其進行處理並存儲以供后續調用。 現在,OAuth流位於InAppBrowser實例中,不受我的控制。

我真的很沮喪,因為我看到OAuth流程在后端運行,而前端部分可以在InAppBrowser之外的常規Web應用程序上輕松完成。

我將復制一些前端和后端代碼以提供更多上下文,希望這有助於理解問題。

處理OAuth流程的前端:

  public logInWithInstagram(): Promise<any>{
    var callbackURL = environment.token_auth_config.apiBase + "/omniauth/instagram/callback";
    var oauthURL = environment.token_auth_config.apiBase + "/auth/instagram";
    var parsedResponse = {};

    return new Promise(function(resolve, reject) {
      var browserRef = window.cordova.InAppBrowser.open(oauthURL, "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
      browserRef.addEventListener("loadstart", (event) => {
        if ((event.url).indexOf(callbackURL) === 0) {
          browserRef.removeEventListener("exit", (event) => {});
          browserRef.close();
          var responseParameters = ((event.url).split("?")[1]).split("&");
          var parsedResponse = {};
          for (var i = 0; i < responseParameters.length; i++) {
            parsedResponse[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
          }
          if (typeof(parsedResponse["code"]) !== 'undefined' && parsedResponse["code"] !== null) {
            // Successful Instagram OAuth, backend has already created the user by now
            resolve(parsedResponse);
          } else {
            reject("Problem authenticating");
          }
        }
      });
      browserRef.addEventListener("exit", function(event) {
        reject("The sign in flow was canceled");
      });
    });
  }

后端,用於創建用戶並處理回調URL的部分:

class Users::OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController

  def redirect_callbacks    
    @user = User.from_omniauth(request.env["omniauth.auth"])

    if @user.persisted?
      sign_in_and_redirect @user
    else
      session["devise.instagram_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end

  end

  def failure
    redirect_to root_path
  end
end

任何幫助,策略或想法,我都將不勝感激。 非常感謝你!

Angular2令牌位於Alpha中,並且尚未處理返回給inAppBrowser的憑據。

我們最終分叉了該項目,並在angular2-token包中添加了一個邏輯分支來解決該問題。

仍然有點麻煩(例如,oAuthLogin尚未返回可觀察到的消息,您必須輪詢登錄成功),但是它可以工作。

如果您想嘗試一下,該軟件包就在這里: https : //github.com/chadnaylor/angular2-token-ionic3

除了離子邏輯外,它與angular2-token基本相同。 希望我們將其清理干凈后再將其合並。

如果您想自己進行調整,則我們更改的內容如下所示:

browser.on('loadstop').subscribe((ev: InAppBrowserEvent) => {
        if (0 === ev.url.indexOf(this.atOptions.oAuthBrowserCallback)) {
          browser.executeScript({code: "requestCredentials();"})
            .then((credentials) => {
              // alert(JSON.stringify(credentials[0]));
              this.getAuthDataFromPostMessage(credentials[0]);

              let pollerObserv = Observable.interval(400);

              let pollerSubscription = pollerObserv.subscribe(() => {
                if(this.userSignedIn()){
                  pollerSubscription.unsubscribe();
                  browser.close();
                }
              });

            })
        }

      });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM