反応ネイティブアプリの基本認証を作成する方法を探しています。反応ネイティブアプリの良い例が見つかりませんでした。
これに最適なアプローチは何でしょうか?
ありがとう。
アプリが何らかの形式の認証を実施するHTTP APIと通信する場合、通常、アプリは次の手順に従います。
上記で定義されたワークフローに基づいて、アプリはログインフォームを表示することから始まります。ユーザーが以下のlogin
アクションクリエーターをディスパッチするログインボタンをタップすると、ステップ2が開始されます。
/// actions/user.js
export function login(username, password) {
return (dispatch) => {
// We use this to update the store state of `isLoggingIn`
// which can be used to display an activity indicator on the login
// view.
dispatch(loginRequest())
// Note: This base64 encode method only works in NodeJS, so use an
// implementation that works for your platform:
// `base64-js` for React Native,
// `btoa()` for browsers, etc...
const hash = new Buffer(`${username}:${password}`).toString('base64')
return fetch('https://httpbin.org/basic-auth/admin/secret', {
headers: {
'Authorization': `Basic ${hash}`
}
})
.then(response => response.json().then(json => ({ json, response })))
.then(({json, response}) => {
if (response.ok === false) {
return Promise.reject(json)
}
return json
})
.then(
data => {
// data = { authenticated: true, user: 'admin' }
// We pass the `authentication hash` down to the reducer so that it
// can be used in subsequent API requests.
dispatch(loginSuccess(hash, data.user))
},
(data) => dispatch(loginFailure(data.error || 'Log in failed'))
)
}
}
上記の関数には多くのコードがありますが、コードの大部分が応答をサニタイズしており、抽象化できるという事実に安心してください。
最初に行うことは、アクションLOGIN_REQUEST
ストアを更新し、ユーザーisLoggingIn
を通知します。
dispatch(loginRequest())
これを使用して、アクティビティインジケータ(回転ホイール、「読み込み中...」など)を表示し、ログインビューでログインボタンを無効にします。
次に、HTTP基本認証用にユーザーのユーザー名とパスワードをbase64でエンコードし、リクエストのヘッダーに渡します。
const hash = new Buffer(`${username}:${password}`).toString('base64')
return fetch('https://httpbin.org/basic-auth/admin/secret', {
headers: {
'Authorization': `Basic ${hash}`
}
/* ... */
すべてうまくいった場合は、LOGIN_SUCCESS
アクション。これにより、ストアで認証hash
を取得し、以降のリクエストで使用します。
dispatch(loginSuccess(hash, data.user))
一方、何か問題が発生した場合は、ユーザーに通知する必要もあります。
dispatch(loginFailure(data.error || 'Log in failed')
loginSuccess
、loginFailure
、およびloginRequest
アクションクリエーターはかなり汎用的であり、コードサンプルを実際に保証するものではありません。参照: https://github.com/ peterp/redux-http-basic-auth-example/blob/master/actions/user.js)
減速機も典型的です:
/// reducers/user.js
function user(state = {
isLoggingIn: false,
isAuthenticated: false
}, action) {
switch(action.type) {
case LOGIN_REQUEST:
return {
isLoggingIn: true, // Show a loading indicator.
isAuthenticated: false
}
case LOGIN_FAILURE:
return {
isLoggingIn: false,
isAuthenticated: false,
error: action.error
}
case LOGIN_SUCCESS:
return {
isLoggingIn: false,
isAuthenticated: true, // Dismiss the login view.
hash: action.hash, // Used in subsequent API requests.
user: action.user
}
default:
return state
}
}
ストアに認証ハッシュがあるので、それを後続のリクエストのヘッダーに渡すことができます。
以下の例では、認証されたユーザーの友達のリストを取得しています。
/// actions/friends.js
export function fetchFriends() {
return (dispatch, getState) => {
dispatch(friendsRequest())
// Notice how we grab the hash from the store:
const hash = getState().user.hash
return fetch(`https://httpbin.org/get/friends/`, {
headers: {
'Authorization': `Basic ${hash}`
}
})
.then(response => response.json().then(json => ({ json, response })))
.then(({json, response}) => {
if (response.ok === false) {
return Promise.reject({response, json})
}
return json
})
.then(
data => {
// data = { friends: [ {}, {}, ... ] }
dispatch(friendsSuccess(data.friends))
},
({response, data}) => {
dispatch(friendsFailure(data.error))
// did our request fail because our auth credentials aren't working?
if (response.status == 401) {
dispatch(loginFailure(data.error))
}
}
)
}
}
通常、ほとんどのAPIリクエストは上記と同じ3つのアクションをディスパッチします:API_REQUEST
、API_SUCCESS
、およびAPI_FAILURE
であり、要求/応答コードの大部分をReduxミドルウェアにプッシュできます。
ストアからハッシュ認証トークンを取得し、リクエストをセットアップします。
const hash = getState().user.hash
return fetch(`https://httpbin.org/get/friends/`, {
headers: {
'Authorization': `Basic ${hash}`
}
})
/* ... */
APIレスポンスが401ステータスコードである場合、ストアからハッシュを削除し、ユーザーに再度ログインビューを表示する必要があります。
if (response.status == 401) {
dispatch(loginFailure(data.error))
}
私は一般的に質問に答えており、http-basic-authのみを扱っています。
概念は同じままであると思うので、accessToken
とrefreshToken
をストアにプッシュし、後続のリクエストで抽出します。
リクエストが失敗した場合、accessTokenを更新し、元のリクエストをリコールする別のアクションをディスパッチする必要があります。
私はこの分野の例としてあまり見ていませんが、より多くの報道を必要とするものだと思います。私はまだ自分自身で認証を実装していません。それ以外の場合は、いくつかのコード例を示します。しかし、私はあなたが正しい方向にあなたを助けるかもしれない私が集めたいくつかのリンクにあなたを指すことができます...
認証の実行方法に関係なく、アクセストークン、更新トークン、シークレットトークンを安全に保存する必要があります。 iOSでは、 keychain を使用してそれを行うと思います。Androidは KeyStore のように見えます。 oblador/react-native-keychain 役に立ちますが、まだサポートしていませんAndroid it サポートしているように見えるAndroid =まもなく 。
実際、私はあなたの質問の少なくともいくつかに答えるビデオチュートリアルシリーズに取り組んでいます。ビデオとトランスクリプトおよびサンプルコードは、次の場所にあります。 http://codecookbook.co/post/how-to-build-a-react-native-login-form-with-redux-pt1/