2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OauthSwiftでRefreshing an Access Token

Posted at

OauthSwiftでRefreshing an Access Token

既存 Rails アプリに OAuth 認証を実装する - techiumでOAuth認証対応したWebアプリに対してトークンのリフレッシュを行う。

環境

Refreshing an Access Token

リフレッシュの仕様については以下を参照。

RFC 6749 - The OAuth 2.0 Authorization Framework

refresh_tokenが必要なので取得する。

@refresh_token=nil

refresh_token無い

refresh_tokenの生成を有効化

Doorkeeper gem で OAuth 認可の仕組みをサポートしているが、refresh_tokenを有効にしていなかった。

config/initializers/doorkeeper.rbを修正する。

   # Issue access tokens with refresh token (disabled by default)
-  # use_refresh_token
+  use_refresh_token

デフォルトのまま使ってたけどトークンの有効期限2時間でrefresh_tokenがdisableってどう使うんだよ(デフォルトのまま使うなよ

もう一度動作を確認。

$ irb
>> require 'oauth2'
=> true
>> client_id     = 'hoge'
>> client_secret = 'fuga'
>> redirect_uri  = 'urn:ietf:wg:oauth:2.0:oob'
=> "urn:ietf:wg:oauth:2.0:oob"
>> site          = "https://fierce-wave-40771.herokuapp.com"
=> "https://fierce-wave-40771.herokuapp.com"
>> client = OAuth2::Client.new(client_id, client_secret, :site => site)
=> #<OAuth2::Client:0x00000000925b80 @id="hope", @secret="fuga", @site="https://fierce-wave-40771.herokuapp.com", @options={:authorize_url=>"/oauth/authorize", :token_url=>"/oauth/token", :token_method=>:post, :auth_scheme=>:request_body, :connection_opts=>{}, :connection_build=>nil, :max_redirects=>5, :raise_errors=>true}>
>> code = "foo"
>> token = client.auth_code.get_token(code, :redirect_uri => redirect_uri)
=> #<OAuth2::AccessToken:0x000000015c4120 @client=#<OAuth2::Client:0x00000000925b80 @id="hoge", @secret="fuga", @site="https://fierce-wave-40771.herokuapp.com", @options={:authorize_url=>"/oauth/authorize", :token_url=>"/oauth/token", :token_method=>:post, :auth_scheme=>:request_body, :connection_opts=>{}, :connection_build=>nil, :max_redirects=>5, :raise_errors=>true}, @auth_code=#<OAuth2::Strategy::AuthCode:0x00000000f3b380 @client=#<OAuth2::Client:0x00000000925b80 ...>>, @connection=#<Faraday::Connection:0x00000000f3b010 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.12.1"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions verify=true>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x00000000f3abd8 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp], @app=#<Faraday::Request::UrlEncoded:0x0000000156fc60 @app=#<Faraday::Adapter::NetHttp:0x0000000156fd00 @app=#<Proc:0x0000000156fdf0@/usr/local/rvm/gems/ruby-2.3.1/gems/faraday-0.12.1/lib/faraday/rack_builder.rb:152 (lambda)>, @connection_options={}, @config_block=nil>>>, @url_prefix=#<URI::HTTPS https://fierce-wave-40771.herokuapp.com/>, @proxy=nil>>, @token="3c123b2a51d798b1880f63d5629741ee48ae8f3b716025bd4c663dccb8c807ae", @refresh_token="361c8c16bad6f9bc27a4cd0c7a3d55e1ccfdcf0cb8ff293939a81604208007c3", @expires_in=7200, @expires_at=1526609633, @options={:mode=>:header, :header_format=>"Bearer %s", :param_name=>"access_token"}, @params={"token_type"=>"bearer", "created_at"=>1526602433}>

refresh_tokenも取れるようになった。

OauthSwift でリフレッシュ

やっと本題。
OAuth 2.0 Token Expiration · OAuthSwift/OAuthSwift Wiki

これを参考に組んでみる。

_ = oauthSwift.client.get(
    URLString,
    success: { (_) in
        completion?(oauthToken, nil)
}, failure: { (error) in
    self.refresh(completion: { (token, error) in
        completion?(token, error)
    })
})

refreshの実装は以下のような感じ。

private func refresh(completion: ((String?, Error?) -> Void)?) {
    let keychain = Keychain(service: OauthRailsTutorial.keychainService)
    guard let refreshToken = keychain[OauthRailsTutorial.oauthRefreshTokenKey] else {
        completion?(nil, nil)
        return
    }
    oauthSwift.renewAccessToken(
        withRefreshToken: refreshToken,
        success: { [unowned self] (credential, _, _) in
            self.storeCredential(into: keychain,
                                    credential: credential)
            completion?(credential.oauthToken, nil)
        }, failure: { (error) in
            print(error)
            completion?(nil, error)
    })
}

これで、

取得済みのトークンが有効ならそのまま使用、期限切れならリフレッシュ

と言う実装ができた。

その他

今回作ったものはこちら

kfurue/RxSwiftRailsTutorial at trial-refreshing-token

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?