복붙노트

[RUBY-ON-RAILS] 레일 응용 프로그램에서 Omniauth-으로 OAuth2를 사용하여 토큰을 새로 고침

RUBY-ON-RAILS

레일 응용 프로그램에서 Omniauth-으로 OAuth2를 사용하여 토큰을 새로 고침

나는 OAuth2를 지원하는 사이트에 인증하는 레일에 omniauth-OAuth2를 사용하고 있습니다. 의 OAuth 댄스를 수행 한 후,이 사이트는 나에게 내가 다음 데이터베이스에 계속 다음을 제공합니다 :

만료 또는 내가 같은 작업을 수행하는 사용자 지정 코드를 작성해야 후 자동으로 토큰을 새로 고침하는 omniauth 방법이 있습니까?

사용자 지정 코드를 작성하는 경우, 도우미는 논리를 쓸 수있는 적절한 장소인가?

해결법

  1. ==============================

    1.난 내 모델 User.rb의 코드를 작성하는 이전의 대답과 다른 SO 응답을 사용하므로 Omniauth는 상자에서이 기능을 제공하지 않습니다

    난 내 모델 User.rb의 코드를 작성하는 이전의 대답과 다른 SO 응답을 사용하므로 Omniauth는 상자에서이 기능을 제공하지 않습니다

    def refresh_token_if_expired
      if token_expired?
        response    = RestClient.post "#{ENV['DOMAIN']}oauth2/token", :grant_type => 'refresh_token', :refresh_token => self.refresh_token, :client_id => ENV['APP_ID'], :client_secret => ENV['APP_SECRET'] 
        refreshhash = JSON.parse(response.body)
    
        token_will_change!
        expiresat_will_change!
    
        self.token     = refreshhash['access_token']
        self.expiresat = DateTime.now + refreshhash["expires_in"].to_i.seconds
    
        self.save
        puts 'Saved'
      end
    end
    
    def token_expired?
      expiry = Time.at(self.expiresat) 
      return true if expiry < Time.now # expired token, so we should quickly return
      token_expires_at = expiry
      save if changed?
      false # token not expired. :D
    end
    

    그리고 액세스 토큰을 사용하여 API 호출을하기 전에, 당신은 CURRENT_USER는 사용자 로그인되는 경우이 같은 메서드를 호출 할 수 있습니다.

    current_user.refresh_token_if_expired
    

    나머지 클라이언트 보석을 설치되었는지 확인하고이 지시어는 모델 파일에서 '나머지 클라이언트'를 필요로 필요로 추가 할 수 있습니다. ENV [ 'DOMAIN', ENV [ 'APP_ID'] 및 ENV [ 'APP_SECRET는'] 설정 / 환경 / production.rb (혹은 개발)에 설정할 수있는 환경 변수

  2. ==============================

    2.사실, omniauth - OAuth2를 보석과 의존성, OAuth2를, 모두에 내장 된 일부 새로 고침 논리를 가지고있다.

    사실, omniauth - OAuth2를 보석과 의존성, OAuth2를, 모두에 내장 된 일부 새로 고침 논리를 가지고있다.

    https://github.com/intridea/oauth2/blob/master/lib/oauth2/access_token.rb#L80를 참조하십시오

    # Refreshes the current Access Token
    #
    # @return [AccessToken] a new AccessToken
    # @note options should be carried over to the new AccessToken
    def refresh!(params = {})
      fail('A refresh_token is not available') unless refresh_token
      params.merge!(:client_id      => @client.id,
                    :client_secret  => @client.secret,
                    :grant_type     => 'refresh_token',
                    :refresh_token  => refresh_token)
      new_token = @client.get_token(params)
      new_token.options = options
      new_token.refresh_token = refresh_token unless new_token.refresh_token
      new_token
    end
    

    그리고 https://github.com/intridea/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb#L74에서 :

    self.access_token = access_token.refresh! if access_token.expired?
    

    당신이 omniauth-OAuth2를 직접 그것을 할 수 있지만하지 않을 수 있습니다 그래서 당신은 확실히 OAuth2를이의 라인을 따라 뭔가를 할 수 있습니다 :

    client = strategy.client # from your omniauth oauth2 strategy
    token = OAuth2::AccessToken.from_hash client, record.to_hash
    # or
    token = OAuth2::AccessToken.new client, token, {expires_at: 123456789, refresh_token: "123"}
    token.refresh!
    
  3. ==============================

    3.내가이 문제를 해결하기 위해 Eero의 대답은 경로를 잠금 해제. 나는 나에게 GmailService를 얻을 내 수업을위한 도우미 우려가 있습니다. 이 만료 않다면이 과정의 일환으로, 사용자 개체는 (구글 인증 정보를 포함하는) 확인됩니다. 이 경우,이 서비스를 반환하기 전에 새로 고칩니다.

    내가이 문제를 해결하기 위해 Eero의 대답은 경로를 잠금 해제. 나는 나에게 GmailService를 얻을 내 수업을위한 도우미 우려가 있습니다. 이 만료 않다면이 과정의 일환으로, 사용자 개체는 (구글 인증 정보를 포함하는) 확인됩니다. 이 경우,이 서비스를 반환하기 전에 새로 고칩니다.

    def gmail_service(user)
      mail = Google::Apis::GmailV1::GmailService.new
    
      # Is the users token expired?
      if user.google_token_expire.to_datetime.past?
        oauth = OmniAuth::Strategies::GoogleOauth2.new(
          nil, # App - nil seems to be ok?!
          "XXXXXXXXXX.apps.googleusercontent.com", # Client ID
          "ABC123456" # Client Secret
        )
        token = OAuth2::AccessToken.new(
          oauth.client,
          user.google_access_token,
          { refresh_token: user.google_refresh_token }
        )
        new_token = token.refresh!
    
        if new_token.present?
          user.update(
            google_access_token: new_token.token,
            google_token_expire: Time.at(new_token.expires_at),
            google_refresh_token: new_token.refresh_token
          )
        else
          puts("DAMN - DIDN'T WORK!")
        end
      end
    
      mail.authorization = user.google_access_token
    
      mail
    end
    
  4. ==============================

    4.일부 정보는 여기에 너무 많은 목록에, 여기에 있습니다. 그것은 당신이 사용하는 업체에 의존하고 새로 고침 토큰의 허용 된 사용 할 수 있습니다

    일부 정보는 여기에 너무 많은 목록에, 여기에 있습니다. 그것은 당신이 사용하는 업체에 의존하고 새로 고침 토큰의 허용 된 사용 할 수 있습니다

  5. ==============================

    5.마찬가지로 다른 답변에 나는 그 논리에서 API 상호 작용을 추상화의 인증 및 새로 고침 토큰을 저장하는 모델을 사용하는이 방법을 따랐다.

    마찬가지로 다른 답변에 나는 그 논리에서 API 상호 작용을 추상화의 인증 및 새로 고침 토큰을 저장하는 모델을 사용하는이 방법을 따랐다.

    https://stackoverflow.com/a/51041855/1392282 참조

  6. from https://stackoverflow.com/questions/21707734/refresh-token-using-omniauth-oauth2-in-rails-application by cc-by-sa and MIT license