Skip to content

Latest commit

 

History

History
150 lines (103 loc) · 10.8 KB

README.ja.md

File metadata and controls

150 lines (103 loc) · 10.8 KB

Example of Expo AuthSession

このリポジトリは Expo のAuthSessionを使ったAuthorization Code Flow with PKCE extensionを実装したサンプルコードです。このリポジトリでは次のトピックスを扱います。

  1. iOS/ Web での Expo AuthSession の実装
  2. Facebook 認証
  3. Twitter OAuth2による認証
  4. Twitter 3-legged authorizationによる認証(Twitter OAuth 1-0a)

目次

  1. Demo
  2. 結論
  3. キー概念
  4. Implicit Flow
  5. Authorization Code Flow with PKCE extension
  6. 環境構築

Demo

demo.mov

OAuth 2.0 for Browser-Based Apps

OAuth とはユーザーにリソースへの限定的なアクセスを許可するための仕組みのことで、Browser-based OAuth Flows ではこの処理をブラウザとリダイレクト URI を使って行います。 OAuth ではプライバシーとセキュリティ保護をテーマに色々なプラクティスが考案されてきました。ここでは代表的な OAuth Flow であるImplicit FlowAuthorization Code Flow with PKCE extensionを題材に現在のベストプラクティスを説明します。

結論

  1. 現在のベストプラクティスはAuthorization Code Flow with PKCE extension
  2. Public Client と認可サーバーとのやり取りにはstate parameterを使って CSRF 対策をしよう
  3. リダイレクト URI は認可サーバーに登録されたものと厳密に一致させよう。Ex. 末尾に/があるかないかも含めてチェック!
  4. フロントチャンネルでアクセストークンをやり取りしない!なので Implicit Flow は非推奨。 認可サーバーとのアクセストークンのやり取りは登録済みの Confidential client で行う!
  5. 秘密鍵はフロントに出さない!

キー概念

3 つの主体

主体 概要
Authorization Server ユーザーに developer によるリソースへのアクセスを許可するかを確認し、アクセストークンを発行する。認可サーバーに登録された Public/ Confidential Client 以外からのリクエストを拒否する。 Facebook
Public Client ソースコードが公開されているユーザーのインターフェースとなるクライアント。秘密鍵を持つことは許されない。認可サーバーからの認可レスポンスを登録されたリダイレクト URI で受け取る。 Web SPA/ Mobile アプリ
Confidential Client 認可サーバーに登録されたバックエンドサーバー。クライアント ID、秘密鍵、リダイレクト URI など登録された情報で認可サーバーにアクセストークンを要求する。 バックエンド

2 つのエンドポイント

endpoints 概要
Authorization Endpoint 認可サーバーが提供するユーザーの認可を求めるためのエンドポイント。操作しているユーザーにログイン認証 -> 権限の認可を求めるのがよくある流れ。ユーザーによる認可が完了したら Public Client に認可レスポンスをリダイレクトする。
Token Endpoint 認可レスポンスで受け取った認可コードをアクセストークンに交換するためのエンドポイント。Confidential client が認可サーバーとやり取りする。認可コード単体では何の効果もない。

2 つの代表的な Flow

Flow 概要
Implicit Flow Authorization Endpoint からの認可レスポンスで Public Client が直接アクセストークンを受け取る。認可レスポンス横取り攻撃のため現在では非推奨となっている。
Authorization Code Flow with PKCE extension 現在のベストプラクティス。Authorization Endpoint からの認可レスポンスで Public Client は短命の認可コードを受け取り、それを Confidential client にわたす。Confidential client は認可サーバーの Token Endpoint に対して認可コードを使ってアクセストークンを発行してもらう。この際、登録情報や秘密鍵、PKCE を使ってセキュアな発行要求をする。

Implicit Flow

Implicit Flow

Implicit Flow の攻撃リスク

フロントチャンネルでやり取りされるリダイレクト URI にアクセストークンを含むため、リダイレクト URI を横取りされたり、ブラウザ履歴から漏洩したりと様々なリスクに晒されています。そのため現在ではフロントチャンネルでアクセストークンを直接やり取りする Inplicit Flow は非推奨となっています。

Authorization Code Flow with PKCE extension

Auth Code

Implicit Flow との違い

  • Implicit Flow にはない Token Endpoint が Flow に追加されている。
  • フロントチャンネルでは短命かつそれ自体ではリソースにアクセスできない認可コードを受け取る。
  • 認可コードとアクセストークンの交換は、登録されたバックエンドサーバー(Confidential client)が秘密鍵などと一緒に行い、フロントチャンネルでアクセストークンを露出させない。

PKCE による同一者証明(Proof Key for Code Exchange:ピクシー)

  1. Authorization EndpointToken Endpointへの実行が同一者によって行われたことを証明するための仕組み。
  2. codeVerifierというランダムの文字列をPublic Clientで生成して、Sha-2 アルゴリズム でcodeChallengeにハッシュ化する。[注]Confidential Clientで発行すべきとの意見もあります。
  3. Public ClientAuthorization Endpointを叩くときにcodeChallengeを URL に付与して、認可サーバーに実行者を認識してもらう。
  4. Confidential ClientToken Endpointを叩くときにcodeVerifierを付与して、認可サーバーにAuthorization Endpointと同じ実行者がアクセストークンを要求していることを認識してもらう。
  5. これにより認可コードの横取り攻撃対策となっている。

参考 URL

環境構築

Authorization Server に Confidential/ Public Client を登録する

  1. expo にサインアップして、アカウント名を取得
    https://expo.dev/

  2. twitter dev > User authentication settings
    https://developer.twitter.com/
    リダイレクト URI を登録 https://auth.expo.io/@{Expo Account Name}/expo-authsession-authcodeflow, https://localhost:19006/twitterOAuth2, https://localhost:19006/ Twitter

  3. facebook dev > Facebook Login setting
    https://developers.facebook.com/
    リダイレクト URI を登録 https://auth.expo.io/@{Expo Account Name}/expo-authsession-authcodeflow, https://localhost:19006/ Facebook

.env に credential 情報を記載

cp .env.sample .env
### you get credential info at Authorization Server(Twitter/ Facebook), and write them in .env

ローカル環境構築

### clone source
git clone git@github.com:Minminzei/expo-authsession-authcodeflow.git
cd expo-authsession-authcodeflow
yarn

### docker
docker-compose up -d
docker-compose exec app bash
yarn server

### simulatar
yarn ios
yarn web