2017-09-24 2 views
0

Ruby on Rails 백엔드가있는 Ionic 3 (Angular 4) 앱을 제작하고 있습니다.Ionic 3 및 Rails (devise_token_auth)가있는 OAuth

사용자 및 API 호출 인증을 위해 angular2-tokendevise_token_auth을 사용하고 있습니다. 함께 사용하도록되어 있습니다. 그들이 일하는

방법은 간단하다 : 그들은 만들고 모든 API 호출 헤더에 일부 필드 (즉 auth-token, client, uidexpiry)의 추적합니다.

이메일 signup/login으로 완벽하게 작동합니다. 이제 Instagram OAuth 로그인을 앱에 구현하고 싶습니다.이 앱은 일반적인 Angular 웹 앱에서는 생각할 필요가 없지만 여기서는 Ionic에서 라우팅이나 URL을 제어 할 수 없으므로 이동 전략은 InAppBrowser을 실행하는 것입니다. 내 API 콜백 URL에 도달 할 때이를 감지하기 위해 이벤트를 설정합니다. 기본적으로

: 내가 InAppBrowser

  • 인스 타 그램 로그인 내부 myapi.com/auth/instagram를로드

    1. 는 URL을
    2. InAppBrowser 부하 myapi.com/omniauth/instagram/callback?code=57... 콜백 리디렉션 나는 그것을 감지합니다.

    이 시점에서 나의 백엔드는 Instagram 데이터를 기반으로 사용자를 성공적으로 만들었습니다.

    문제는 클라이언트 측에서 어떻게 처리해야할지 모르겠다는 것입니다.

    이메일/비밀번호로 로그인 할 때 은 POST /auth/sign_in이고 요청 헤더는 auth_token을 포함하고 처리 한 후 이후 통화를 위해 저장합니다. 이제 OAuth 흐름은 내 제어 밖으로 InAppBrowser 인스턴스에 살고 있습니다 ...

    OAuth 흐름이 백엔드 측에서 작동하고 프론트 엔드 부분이 일반 웹 응용 프로그램에서 쉽게 수행 될 수 있으므로 실제로 좌절감을 느낍니다. InAppBrowser 외부. 좀 더 컨텍스트를 제공하기 위해 내 프론트 엔드와 백엔드 코드의 일부를 복사 할 수 있습니다

    , 즉 문제에게의 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 
    

    정말 도움이 될만한 전략이나 아이디어가 있습니다. 고마워요!

  • 답변

    0

    Angular2-token은 alpha 형식이며 아직 inAppBrowser에 반환 된 자격 증명을 처리하지 않습니다.

    우리는 프로젝트를 포크로 만들고 angular2-token 패키지에 논리 분기를 추가하여 문제를 처리했습니다.

    아직 약간의 janky입니다 (예 : oAuthLogin은 관찰 가능 항목을 반환하지 않으며 로그인 성공을 위해 폴링해야 함).https://github.com/chadnaylor/angular2-token-ionic3

    그것은 angular2 토큰을 위해 이온 로직을 제외하고 본질적으로 동일 : 당신이 그것을 밖으로 시도하려는 경우

    패키지는 여기까지입니다. 바라건대 우리는 한번 병합 할 수 있습니다. 조금 청소했습니다.

    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(); 
           } 
           }); 
    
          }) 
         } 
    
         }); 
    
    : 당신이 스스로를 조정하려고 할 경우

    이 비트는 우리가 같은 모양을 변경