2017-03-01 5 views
0

私はちょっと立ち往生して解決策を見つけることができませんでした。フロントエンドにdeviseを、apiにdevise_token_authを使用するレールサイトがあります。フロントエンドは、サーバー側のレンダリングされたページとAPIコールの組み合わせを使用して、ユーザーにデータを表示します。私は純粋な角度ログインを使用する場合 ログインフォームはeventally(ushally 2-3提出を)動作します:Devise、devise_token_auth、およびng-token-authの認証に関する問題

%div{'ng-controller'=>'logInCtrl'} 
    %h2 Log In 
    %div{:layout=>'column'} 
    %div{:flex=>20} 
    %div{:flex=>60, :layout=>'column'} 
     = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| 
     %div{:layout=>'column'} 
      %md-input-container 
      =f.label :login 
      %input{'ng-model'=>'loginForm.login', :autofocus => 'true'} 
      %md-input-container 
      = f.label :password 
      %input{:type=>'password', 'ng-model'=>'loginForm.password', :autocomplete => 'off'} 

      %md-input-container 
      %md-button.md-raised.md-primary{'ng-click'=>'submitMe()'} 
       -#{:type=>'submit'} 
       %md-icon.mdi.mdi-account-key 
       Log In 

:coffee 
    myApp.controller 'logInCtrl', ($scope, $resource, $http, $mdDialog, $auth) -> 
    $scope.submitMe =() -> 
     $auth.submitLogin($scope.loginForm).then((resp)-> 
     location.replace('/users/sign_in') 
    ) 

私は、正しい情報がサーバーによってレンダリングされた標準のPOSTメソッドを使用しますが、トークンセットが存在しない場合にはng-token-auth

# POST /resource/sign_in 
    def create 
    super do |user| 
     newAuth = user.create_new_auth_token 
     response.headers.merge!(newAuth) 
    end 
    end 

を私はこのアプローチを持っている問題はそれがなかったので、NG-トークン認証は、ヘッダからトークンを拾うことがないということです:私は使用してセッション#上で手動でトークンヘッダを作成して生成して送信することができます要求を行う。私は手でトークンヘッダーを設定する方法を探しました。

- 私は最終的にはoauthソリューションに移行していないので、私が使用している回避策はすべて移植する必要があります。 - サーバー側のレンダリングでは、デザイン要素の処理だけでなく、機能のオンとオフを切り替える必要があります。また、current_userの要素を使用して、ユーザーの場所に基づいてテーブル名のサブセットを設定します。

答えて

0

少しの研究と少し時間がたってから、私はちょっとハックリですが、うまくいく解決策を思いつきました。

Deviseが新しいセッションを作成すると、設定ファイルで指定されたルートにリダイレクトが呼び出されるため、変数の設定は失われます。 2番目の問題は、ng-token-authがサインイン機能で設定されたトークンを設定して使用するだけなので、ページヘッダーを介してトークンを送信するだけでは検出されません(これはコードではなくブラウザの制限です)。

ng-token-authと私のユーザーのための標準のデバイス認証を別々に繰り返してみたところ、最初にdeviseでユーザーを認証し、何とかng-token-authというトークンを設定する方が良いと結論づけました。そこで、私はng-token-authがログイン経由でトークンを受け取ったときに実際に何をしたかを調べ始めました。それは2つのクッキーを設定することが判明しました:

currentConfigName |デフォルト| ドメイン |/| 予定日

auth_headers | URLでエンコードされたトークンデータ | ドメイン |/| 予定日

今問題は、新しく生成されたトークンをフロントエンドに渡す方法でした。これは私が思ったよりも簡単になった。 Railsの呼び出し間で永続化される唯一のデータはセッションデータなので、新しい鍵を生成するように私のApplicationControllerに通知したセッションデータにフラグを追加することが理にかなっていると判断しました。

まず私は、これはTrueからtokenという名前のセッション変数を設定しますDevise::SessionsController#create

def create 
    super do |user| 
    session[:token] = true 
    end 
end 

を拡張しました。ApplicationControllerよりも私が追加:

before_filter :set_token 

    def set_token 
    if session[:token] && user_signed_in? 
     newAuth = current_user.create_new_auth_token 
     response.headers.merge!(newAuth) 
     @auth_token = newAuth 
     session.delete(:token) 
    else 
     @auth_token = false 
    end 
    end 

この前フィルタはsession[:token]を探し、セットは「create_new_auth_token機能がにS 『サインイン』は、現在のユーザーdevise-token-auth呼び出す場合。このヘッダー情報は、出力ページヘッダーに書き込まれるだけでなく、変数@auth_tokenに割り当てられます。 %bodyタグ

- if @auth_token 
    :coffee 
    myApp.controller 'cookieController', ($scope, $resource, $http, $mdDialog, $auth, ipCookie) -> 
     ipCookie('auth_headers', "{\"access-token\": \"#{@auth_token['access-token']}\",\"token-type\": \"Bearer\",\"client\": \"#{@auth_token['client']}\",\"expiry\": \"#{@auth_token['expiry']}\",\"uid\": \"#{@auth_token['uid']}\"}", {path: "/",expires: 9999,expirationUnit: 'days',secure: false}) 
     ipCookie('currentConfigName', 'default', {path: "/",expires: 9999,expirationUnit: 'days',secure: false}) 
    %div{'ng-controller'=>'cookieController'} 

これは@auth_tokenに書き込まれたデータを使用して空divタグと角度コントローラとipCookie機能を追加した後 最後ビュー/ laoyouts/applicationhtml.hamlこのコードブロックは右側に追加され(ng-token-authが必要)を使用して必要なCookieを書き込みます。

いくつかの注意事項:

  • ユーザーが自分のサイトにサインインしているとき、彼らは自分の資格情報に応じて、2つのページのいずれかにリダイレクトすることができるので、私はメインのレイアウト・ページとApplicationControllerにコードブロックを追加しました。これにより、コードトークンに送信されるページが生成され、コードブロックが挿入されても確実になります。
  • 空のdivを作成してコントローラーを割り当てる代わりに、おそらくクッキーの生成を処理するより良い方法があることは知っています。私はより洗練されたソリューションにオープンしています。
関連する問題