現状・条件
- 自宅サーバ環境:CentOS 7.6
- WEB Server : Nginx 1.17.5
- Application Server : uSWGI 2.0.18
- WordPress バージョン:5.3.1
- WordPress のテーマ:Cocoon 2.0.2.4
- この記事は Nginx + uWSGI 環境で Twitter 認証を行うための記事です。設定するには下記の記事をご覧ください。
→ Nginx:
Django REST framework API サーバと Nginx WEB サーバを連動する|CentOS 7
→ uWSGI:
Permission エラーの無い uWSGI と Nginx で Django API サーバを構築する方法 |CentOS 7
- Twitter API を利用して OAuth 認証を行うには Twitter Developer への登録が必要です。
- バックエンド環境は django-rest-auth、django-allauth を利用します。
- フロントエンドでは Create React App で React、Redux、Meterial-UI の構成です。
バックエンド環境を設定する
django-rest-auth の設定を行います。
パッケージをインストールします。
pip install django-rest-auth pip install django-rest-framework
以下、$ django-admin startproject myproject
でプロジェクトを作成したと前提します。
myproject/settings.py ファイルの INSTALLED_APPS に rest_auth を追加します。
INSTALLED_APPS = ( ..., 'rest_framework', 'rest_framework.authtoken', ..., 'rest_auth' )
rest_auth URLを myproject/urls.py に追加します。
urlpatterns = [ ..., url(r'^rest-auth/', include('rest_auth.urls')) ]
以下、$ python manage.py startapp oauth-test
で Django アプリを作成したと前提します。
TwitterLogin View を oauth-test/views.py に追加 ( 作成 ) します。
from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter from rest_auth.registration.views import SocialLoginView from rest_auth.social_serializers import TwitterLoginSerializer class TwitterLogin(SocialLoginView): serializer_class = TwitterLoginSerializer adapter_class = TwitterOAuthAdapter
TwitterLogin View 用の URL を myproject/urls.py に追加します。
from oauth-test.views import TwitterLogin urlpatterns += [ ..., url(r'^rest-auth/twitter/$', TwitterLogin.as_view(), name='twitter_login') ]
追加内容を Database に適用します。
[admin@centos7 backend]$ source activate py37 (py37) [admin@centos7 backend]$ python manage.py makemigrations (py37) [admin@centos7 backend]$ python manage.py migrate (py37) [admin@centos7 backend]$
/rest-auth/twitter へアクセスして動作確認を行います。
Twitter Login の動作確認方法は、
Twitter Developer へアクセス >「Keys and tokens」タブをクリック > 「Access token & access token secret」>「Access token」と「Access token secret」( 最初は要生成 ) を ▲ の「Access token」と「Token secret」欄にコピペして「POST」ボタンをクリックします。
すると、下記のように 認証キー が表示されれば設定に問題ありません。
「Access token」と「Access token secret」はフロントエンドでも使用しますので適宜メモって置きましょう!
django-allauth の設定を行います。
パッケージをインストールします。
pip install django-allauth
myproject/settings.py ファイルの INSTALLED_APPS に django.contrib.sites、allauth、 allauth.account、rest_auth.registration を追加します。
また、SITE_ID も設定します。( ※ SITE_ID の確認方法は こちら )
INSTALLED_APPS = ( ..., 'django.contrib.sites', 'allauth', 'allauth.account', 'rest_auth.registration', ) SITE_ID = 1
rest_auth.registration URLを myproject/urls.py に追加します。
urlpatterns = [ ..., url(r'^rest-auth/', include('rest_auth.urls')), url(r'^rest-auth/registration/', include('rest_auth.registration.urls')) ]
Social Authentication を利用するため、myproject/settings.py ファイルの INSTALLED_APPS に allauth.socialaccount、allauth.socialaccount.providers.twitter を追加します。
INSTALLED_APPS = ( ..., 'rest_framework', 'rest_framework.authtoken', 'rest_auth' ..., 'django.contrib.sites', 'allauth', 'allauth.account', 'rest_auth.registration', ..., 'allauth.socialaccount', 'allauth.socialaccount.providers.twitter', )
追加内容を Database に反映します。
[admin@centos7 backend]$ source activate py37 (py37) [admin@centos7 backend]$ python manage.py makemigrations (py37) [admin@centos7 backend]$ python manage.py migrate (py37) [admin@centos7 backend]$
※ CentOSで pyenv & Anaconda の Python 環境構築方法は こちら
Twitter Developer へアプリを登録します。
- Step 1有効な Twitter アカウントで Twitter Developer サイトへアクセスします。
画面右上の「Create an Apps」ボタンをクリックします。
- Step 2表示された各項目をご記入の上、アプリの登録を済ませてください。
- 特に、Callback URLs 項目には、http://{{yourdomain}}.com/accounts/twitter/login/callback/ のように入力してください。( django-allauth 仕様 )
- また、ユーザーが各セッションを承認せずにログインできるようにするには「Enable Sign in with Twitter」にチェックを入れて置きます。
Twitter Developer での設定はこれで完了です。
次は Django 側で Twitter アプリの設定を行います。
Django Admin パネルで Social Application を登録します。
/admin/socialaccount/socialapp/ にアクセスし、画面右上の「ADD SOCIAL APPLICATION」ボタンをクリックして各項目を下記のように入力します。
- Provider:Twitter を選択
- Name:Twitter( 任意 )
- Client id:Twitter Developer へアクセス、「Details」>「Keys and tokens」> 「Consumer API keys」>「API key」をコピペします。
- Secret key:同じく、「Details」>「Keys and tokens」> 「Consumer API keys」>「API secret key」をコピペします。
- Key:空欄のまま
- Sites:利用するサイトを選択し、「Chosen sites」に移動して置きます。
内容の確認の上、「SAVE」ボタンをクリックして完了します。
その他の設定
E-Mail Verification を行わないように。( 任意 )
ここではソーシャルアカウントのメールアドレスの確認 ( E-Mail Verification ) を行わないように設定するため、myproject/settings.py ファイルに下記を追加します。( 追加場所は任意
... SOCIALACCOUNT_EMAIL_VERIFICATION = 'none' ...
※ メール認証方法は下記の記事をご参考ください。
メール認証方式のユーザ登録機能を実装する〜Reactjs + Django 環境|macOS〜
フロントエンド環境を設定する
フロントエンドは下記の記事のように設定した状態から設定を追加します。
React アプリを Create React App で設置&設定する | CentOS 7.6
下記のようにファイルを作成します。( ファイル名や位置は任意 )
src/actions/socialConfig.json
{ "twitterAuth": { "access_token": "your-access-token", "token_secret":"your-token-secret" }, "GOOGLE_CLIENT_ID": "XXXXX", "FACEBOOK_APP_ID": "XXXXX" }
scr/actions/authUrls.js
// URL の最後に "/" をつける事! export const ROOT_URL = "https://your-api-server-domain/"; export const AuthUrls = { ... TWITTER_REQ_TOKEN: `${ROOT_URL}rest-auth/twitter/`, TWITTER_LOGIN: `${ROOT_URL}accounts/twitter/login/`, ... };
src/actions/authActions.js
先ほど、Twitter Login の動作確認方法のところで取得した「Access token」と「Access token secret」を利用して認証キーを取得した後、必要な処理を行います。
ここでは、取得した認証キーを Local Storage に保存して Current User 情報をメイン画面に表示する処理を行います。
import axios from "axios"; import { AuthUrls } from "actions/actionUrls"; ... export const twitterReqToken = () => dispatch => { const oauthValues = { access_token: conf.twitterAuth.access_token, token_secret: conf.twitterAuth.token_secret }; const twitterReqURL = AuthUrls.TWITTER_REQ_TOKEN; return axios .post(twitterReqURL, oauthValues) .then(res => { if (res.status === 200) { const token = res.data.key; setStorageItem("token", token); dispatch(authLogin(token)); } }) .then(() => { const token = getUserToken(store.getState()); dispatch(getCurrentUser(token)); history.push("/"); }) .catch(error => { console.log(error); }); };
それでは、実際の Twitter Login 処理を行う為のファイルを作成します。
src/views/TwitterLoginPage.js
import { connect } from "react-redux"; import { bindActionCreators } from "redux"; import { twitterReqToken } from "actions/authActions.js"; import TwitterLoginPageView from "views/TwitterLoginPageView.js"; const mapDispatchToProps = dispatch => ({ onTwitterReqToken: bindActionCreators(twitterReqToken, dispatch) }); const TwitterLoginPage = connect( mapDispatchToProps )(TwitterLoginPageView); export default TwitterLoginPage;
src/views/TwitterLoginPageView.js
import React from "react"; import { Redirect } from "react-router-dom"; class TwitterLoginPageView extends React.Component { componentDidMount() { this.props.onTwitterReqToken(); } render() { return <Redirect to="/" />; } } export default TwitterLoginPageView;
src/views/LoginPage.js ( 抜粋 )
Twitter へログイン可能なボタンなどを設置して、TWITTER_LOGIN リンクを指定します。
import React from 'react'; ... class LoginPage extends React.Component { render() { return ( ... <Button justIcon href={AuthUrls.TWITTER_LOGIN} color="transparent" > <i className={"fab fa-twitter"} /> </Button> ... ); } } export default LoginPage;
ボタンをクリックすると、https://api.twitter.com/oauth/authenticate?..
のようなTwitter サイトにリダイレクトされ、Twitter アカウントで「Sign In」できます。
↓↓↓
また、認証に成功するとバックエンドの Database に該当アカウントが自動登録されますので下記のところで詳細を確認してみましょう!
/admin/socialaccount/socialaccount/
/admin/socialaccount/socialtoken/
/admin/users/user/
※ しかし、ここまでの設定では認証後に API サーバにリダイレクトされてしまいます。
次の設定で、ログインした状態でサービス URL にリダイレクトされるようになります。
Twitter 認証後の URL のリダイレクト設定
バックエンド:
API サーバの URL とサービス URL が異なる場合、普段 NGINXで Reverse Proxyを設定しますが ( 今回の Twitter 認証では効かなかったため )、django-allauth 側のアダプターメソッドをオーバーライドして認証後のURLのリダイレクト ( get_login_redirect_url ) 設定を行います。
# myproject/settings.py: ACCOUNT_ADAPTER = 'myproject.oauth-test.adapter.MyAccountAdapter' # myproject/oauth-test/adapter.py: from allauth.account.adapter import DefaultAccountAdapter from django.shortcuts import resolve_url class MyAccountAdapter(DefaultAccountAdapter): def get_login_redirect_url(self, request): assert request.user.is_authenticated twitter = False for keys,vals in request.META.items(): if (keys == 'PATH_INFO'): if (vals == '/accounts/twitter/login/callback/'): twitter = True if twitter : return resolve_url('https://your-service-url/twitter') return resolve_url('https://your-service-url')
フロントエンド:
リダイレクトリンク ( /twitter ) の処理を追加します。
// src/routes/index.js import TwitterLoginPage from "views/authspace/Login/TwitterLoginPage.js"; ... var indexRoutes = [ ... { path: "/twitter", name: "TwitterLoginPage", component: TwitterLoginPage }, .... } export default indexRoutes;
これで設定が完了します。
各自のTwitter アカウントでログインしてみましょう。
あとがき
Reactjs+Django の連携事例などの情報は少なかった為、設定するのに少々時間が掛かりましたが、このような構成をお考えの方に少しでもヒントになれればと。。
NGINX の Reverse Proxy 設定で動作させる方法は今後の課題として残して置きます。
コメント
記事を見させていただき無事、実装できました。
nginx の reverse proxy を使用してリダイレクトする方法を教えていただけたら幸いです。