簡體   English   中英

Devise,devise_token_auth和ng-token-auth的身份驗證問題

[英]Authentication issue with Devise, devise_token_auth, and ng-token-auth

我有點卡住了,我一直找不到解決方法。 我有一個Rails網站,它在前端使用devise,在api上使用devise_token_auth。 前端結合使用服務器端呈現的頁面和api調用來向用戶顯示數據。 如果我使用純角度登錄,則登錄表單最終將起作用(通常需要提交2-3個):

%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設置ng-token-auth 我可以使用以下命令在session#create上手動生成和發送令牌頭:

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

我使用這種方法的問題是ng-token-auth從未從標頭中提取令牌,因為它沒有發出請求。 我一直在尋找一種手動設置令牌標頭的方法,但是沒有運氣。

-一方面,我最終不會轉向oauth解決方案,因此無論我使用什么解決方法,都需要移植到該解決方案。 -我應該提到服務器端渲染要照顧到設計元素以及打開和關閉功能。 我還使用current_user的元素根據用戶位置設置表名稱的子集。

經過一些研究和一段時間后,我想出了一個可行的解決方案,盡管有點棘手。

當Devise創建新會話時,將重定向到配置文件中指定的路由,因此丟失任何設置。 第二個問題是ng-token-auth將僅設置和使用在登錄功能期間設置的令牌,因此未檢測到僅通過頁面標題發送令牌(這是瀏覽器的限制,而不是代碼)。

在嘗試對我的用戶使用ng-token-auth和標准的devise身份驗證進行了不同的迭代之后,我得出的結論是,最好首先使用devise對用戶進行授權,然后以某種方式使用ng-token-auth設置令牌; 因此我開始研究ng-token-auth通過登錄接收令牌時的實際作用。 事實證明,它設置了兩個cookie:

currentConfigName | 默認值 | / | 過期日期

auth_headers | url編碼的令牌數據 | | / | 過期日期

現在的問題是如何將新生成的令牌傳遞到前端。 這使我們比我想象的要簡單。 由於在Rails調用之間唯一保留的數據是會話數據,因此我決定在會話數據中添加一個標志是有意義的,這標志着我的ApplicationController生成了一個新密鑰。

首先,我擴展了Devise::SessionsController#create

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

這會將名為token的會話變量設置為True 比在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

此before過濾器將查找session[:token] ,如果set調用devise-token-authcreate_new_auth_token函數以“登錄”當前用戶。 該標頭信息既被寫入傳出頁標頭,也被分配給變量@auth_token 最后,在views / laoyouts / applicationhtml.haml中,將此代碼塊添加到%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'}

這將添加一個空的div標簽和角度控制器,該控制器使用寫入@auth_token的數據和ipCookie函數( ng-token-auth )來寫入必要的cookie。

一些注意事項:

  • 我將代碼塊添加到主布局頁面和ApplicationController因為當用戶登錄到我的網站時,根據其憑據,他們可能會重定向到兩個頁面之一。 這樣可以確保無論將它們發送到代碼令牌的哪個頁面都被生成,並且插入了代碼塊。
  • 我知道,可能有更好的方法來處理Cookie的生成,而不是創建一個空的div並為其分配控制器。 我願意接受更優雅的解決方案。

暫無
暫無

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

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