AngularJSなどの機能豊富なフロントエンドフレームワークの登場により、データ操作/検証、認証など、ますます多くのロジックがフロントエンドに実装されています。 AngularJS用の使いやすいトークンベースの認証モジュールであるSatellizerは、AngularJSに認証メカニズムを実装するプロセスを簡素化します。ライブラリには、Google、Facebook、LinkedIn、Twitter、Instagram、GitHub、Bitbucket、Yahoo、Twitchのサポートが組み込まれています。 、およびMicrosoft(Windows Live)アカウント。
この記事では、次のような非常に単純なWebアプリを作成します。 ここに これにより、ログインして現在のユーザーの情報を確認できます。
これらは、アプリがユーザーシステムの統合を開始したときによく遭遇する2つの恐ろしい言葉です。ウィキペディアによると:
認証 エンティティによって真であると主張された単一のデータ(データ)の属性の真偽を確認する行為です。
承認 情報セキュリティやコンピュータセキュリティ全般、特にアクセス制御に関連するリソースへのアクセス権を指定する機能です。
素人の言葉で言えば、何人かの人々がそれに取り組んでいるブログのウェブサイトの例を見てみましょう。ブロガーは記事を書き、マネージャーはコンテンツを検証します。各ユーザーはシステムに認証(ログイン)できますが、権限(承認)が異なるため、ブロガーはコンテンツを検証できませんが、マネージャーは検証できます。
この非常に詳細なチュートリアルなどのチュートリアルに従うことで、AngularJSで独自の認証システムを作成できます。 JSON Web Tokenチュートリアル:LaravelとAngularJSの例 。 JWT(JSON Web Token)について詳しく説明し、ローカルストレージとHTTPインターセプターを直接使用してAngularJSで認証を実装する簡単な方法を示しているため、この記事を読むことをお勧めします。
では、なぜサテライザーなのか?主な理由は、FacebookやTwitterなどの少数のソーシャルネットワークログインをサポートしていることです。最近、特にモバイルで使用されるWebサイトの場合、ユーザー名とパスワードの入力は非常に面倒であり、ユーザーはほとんど支障なくWebサイトを使用できることを期待しています。ソーシャルログインを使用して。各ソーシャルネットワークのSDKを統合し、それらのドキュメントに従うことは非常に反復的であるため、最小限の労力でこれらのソーシャルログインをサポートすると便利です。
さらに、Satellizerは アクティブ Githubのプロジェクト。これらのSDKは頻繁に変更され、ドキュメントを時々読みたくないため、ここではアクティブが重要です(Facebook SDKを使用している人なら誰でも、それがどれほど煩わしいかを知っています)。
ここから物事が面白くなり始めます。
通常のログイン/登録(つまり、ユーザー名、パスワードを使用)メカニズムを備え、ソーシャルログインもサポートするWebアプリを構築します。このWebアプリは、3ページしかないため、非常にシンプルです。
バックエンドには、PythonとFlaskを使用します。 PythonとフレームワークFlaskは非常に表現力豊かなので、コードを他の言語/フレームワークに移植するのはそれほど難しくないことを願っています。もちろん使用します AngularJS フロントエンド用。また、ソーシャルログインについては、現時点で最も人気のあるソーシャルネットワークであるFacebookとのみ統合します。
はじめましょう!
コードを構造化する方法は次のとおりです。
- app.py - static/ - index.html - app.js - bower.json - partials/ - login.tpl.html - home.tpl.html - secret.tpl.html
すべてのバックエンドコードは app.py 。フロントエンドコードはstatic /フォルダーに配置されます。デフォルトでは、Flaskはstatic /フォルダーのコンテンツを自動的に提供します。すべての部分ビューはstatic / partial /にあり、ui.routerモジュールによって処理されます。
バックエンドのコーディングを開始するには、Python 2.7。*が必要であり、pipを使用して必要なライブラリをインストールします。もちろん使用できます virtualenv Python環境を分離します。以下は、requirements.txtに入れる必要のあるPythonモジュールのリストです。
Flask==0.10.1 PyJWT==1.4.0 Flask-SQLAlchemy==1.0 requests==2.7.0
これらすべての依存関係をインストールするには:
pip install -r requirements.txt
に app.py Flaskをブートストラップするための初期コードがいくつかあります(簡潔にするためにimportステートメントは省略されています)。
app = Flask(__name__) @app.route('/') def index(): return flask.redirect('/static/index.html') if __name__ == '__main__': app.run(debug=True)
次は 初期化 bowerを実行し、AngularJSとui.routerをインストールします。
bower init # here you will need to answer some question. when in doubt, just hit enter :) bower install angular angular-ui-router --save # install and save these dependencies into bower.json
これらのライブラリをインストールしたら、AngularJSとui-routerをに含める必要があります index.html ホーム、ログイン、シークレットの3ページのルーティングを作成します。
Home Login Secret
以下は、ルーティングを構成するためにmain.jsで必要なコードです。
var app = angular.module('DemoApp', ['ui.router']); app.config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('home', { url: '/home', templateUrl: 'partials/home.tpl.html' }) .state('secret', { url: '/secret', templateUrl: 'partials/secret.tpl.html', }) .state('login', { url: '/login', templateUrl: 'partials/login.tpl.html' }); $urlRouterProvider.otherwise('/home'); });
この時点で、サーバーpythonを実行している場合 app.py 、この基本的なインターフェイスは次の場所にある必要があります http:// localhost:5000
この時点で、[ホーム]、[ログイン]、および[シークレット]リンクが機能し、対応するテンプレートのコンテンツが表示されます。
おめでとうございます。スケルトンの設定が完了しました。エラーが発生した場合は、 GitHubのコード
この手順を完了すると、メールアドレスとパスワードを使用して登録/ログインできるウェブアプリができあがります。
最初のステップは、バックエンドを構成することです。ユーザーモデルと、特定のユーザーのJWTトークンを生成する方法が必要です。以下に示すユーザーモデルは非常に単純化されており、ifフィールドなどの基本的なチェックも実行しません。 Eメール 「@」を含む、またはifフィールド パスワード 6文字以上含まれているなど。
class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(100), nullable=False) password = db.Column(db.String(100)) def token(self): payload = { 'sub': self.id, 'iat': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(days=14) } token = jwt.encode(payload, app.config['TOKEN_SECRET']) return token.decode('unicode_escape')
Pythonでjwtモジュールを使用して、JWTでペイロード部分を生成します。 iatとexpの部分は、トークンが作成されて期限切れになったタイムスタンプに対応します。このコードでは、トークンは2週間で期限切れになります。
モデルユーザーが作成された後、「ログイン」および「登録」エンドポイントを追加できます。両方のコードは非常に似ているので、ここでは「レジスタ」の部分だけを示します。デフォルトでは、Satellizerがエンドポイントを呼び出すことに注意してください / auth / login そして / auth / signup それぞれ「ログイン」と「登録」に。
@app.route('/auth/signup', methods=['POST']) def signup(): data = request.json email = data['email'] password = data['password'] user = User(email=email, password=password) db.session.add(user) db.session.commit() return jsonify(token=user.token())
最初にcurlを使用してエンドポイントを確認しましょう。
curl localhost:5000/auth/signup -H 'Content-Type: application/json' -X POST -d '{'email':' [email protected] ','password':'xyz'}'
結果は次のようになります。
{ 'token': 'very long string….' }
バックエンド部分の準備ができたので、フロントエンドを攻撃しましょう!まず、satellizerをインストールし、main.jsに依存関係として追加する必要があります。
bower install satellizer --save
依存関係としてsatellizerを追加します。
var app = angular.module('DemoApp', ['ui.router', 'satellizer']);
satellizerでのログインとサインアップは、これまでのすべてのセットアップと比較して、実際には非常に簡単です。
$scope.signUp = function () { $auth .signup({email: $scope.email, password: $scope.password}) .then(function (response) { // set the token received from server $auth.setToken(response); // go to secret page $state.go('secret'); }) .catch(function (response) { console.log('error response', response); }) };
コードの設定に問題がある場合は、 GitHubのコード 。
はい、その通りです!これまで、誰でもログインせずにシークレットページにアクセスできます。
AngularJSにインターセプターを追加して、誰かがシークレットページにアクセスし、このユーザーがログインしていない場合に、ログインページにリダイレクトされるようにします。
まず、シークレットページを他のページと区別するためにrequiredLoginフラグを追加する必要があります。
.state('secret', { url: '/secret', templateUrl: 'partials/secret.tpl.html', controller: 'SecretCtrl', data: {requiredLogin: true} })
「データ」部分は、ルーティングが変更されるたびに発生する$ stateChangeStartイベントで使用されます。
app.run(function ($rootScope, $state, $auth) { $rootScope.$on('$stateChangeStart', function (event, toState) { var requiredLogin = false; // check if this state need login if (toState.data && toState.data.requiredLogin) requiredLogin = true; // if yes and if this user is not logged in, redirect him to login page if (requiredLogin && !$auth.isAuthenticated()) { event.preventDefault(); $state.go('login'); } }); });
これで、ユーザーはログインせずにシークレットページに直接移動することはできません。
いつものように、このステップのコードは見つけることができます ここに 。
現時点では、秘密のページには本当に秘密はありません。そこに個人的なものを入れましょう。
このステップは、有効なトークンを持っているなど、認証されたユーザーのみがアクセスできるエンドポイントをバックエンドに作成することから始まります。エンドポイント /ユーザー 以下は ユーザーID そして Eメール トークンに対応するユーザーの。
@app.route('/user') def user_info(): # the token is put in the Authorization header if not request.headers.get('Authorization'): return jsonify(error='Authorization header missing'), 401 # this header looks like this: “Authorization: Bearer {token}” token = request.headers.get('Authorization').split()[1] try: payload = jwt.decode(token, app.config['TOKEN_SECRET']) except DecodeError: return jsonify(error='Invalid token'), 401 except ExpiredSignature: return jsonify(error='Expired token'), 401 else: user_id = payload['sub'] user = User.query.filter_by(id=user_id).first() if user is None: return jsonify(error='Should not happen ...'), 500 return jsonify(id=user.id, email=user.email), 200 return jsonify(error='never reach here...'), 500
ここでも、モジュールを利用します jwt 「Authorization」ヘッダーに含まれているJWTトークンをデコードし、トークンの有効期限が切れているか無効な場合を処理します。
curlを使用してこのエンドポイントをテストしてみましょう。まず、有効なトークンを取得する必要があります。
curl localhost:5000/auth/signup -H 'Content-Type: application/json' -X POST -d '{'email':' [email protected] ','password':'xyz'}'
次に、このトークンを使用します。
curl localhost:5000/user -H 'Authorization: Bearer {put the token here}'
これはこの結果をもたらします:
{ 'email': ' [email protected] ', 'id': 1 }
次に、このエンドポイントをシークレットコントローラーに含める必要があります。通常の$ httpモジュールを使用してエンドポイントを呼び出す必要があるため、これは非常に簡単です。トークンはSatellizerによってヘッダーに自動的に挿入されるため、トークンを保存してから適切なヘッダーに配置するための詳細を気にする必要はありません。
getUserInfo(); function getUserInfo() { $http.get('/user') .then(function (response) { $scope.user = response.data; }) .catch(function (response) { console.log('getUserInfo error', response); }) }
最後に、秘密のページに本当に個人的なものがあります!
このステップのコードはオンです GitHub 。
冒頭で述べたように、Satellizerの良いところは、ソーシャルログインの統合がはるかに簡単になることです。このステップの最後に、ユーザーは自分のFacebookアカウントを使用してログインできます。
最初に行うことは、Facebook開発者ページでアプリケーションを作成して アプリケーションID と秘密のコード。従ってください Developers.facebook.com/docs/apps/register Facebook開発者アカウントをまだ持っていない場合は作成し、Webサイトアプリを作成します。その後、以下のスクリーンショットのように、アプリケーションIDとアプリケーションシークレットを取得します。
ユーザーがFacebookに接続することを選択すると、Satellizerは認証コードをエンドポイントに送信します / auth / facebook 。この認証コードを使用すると、バックエンドはFacebookからアクセストークンを取得できます / oauth Facebook Graph APIを呼び出して、場所、user_friends、ユーザーの電子メールなどのユーザー情報を取得できるようにするエンドポイント。
また、ユーザーアカウントがFacebookで作成されたのか、定期的なサインアップで作成されたのかを追跡する必要があります。そのために、 FacebookのID ユーザーモデルに。
facebook_id = db.Column(db.String(100))
Facebookシークレットは、追加する環境変数FACEBOOK_SECRETを介して構成されます app.config 。
app.config['FACEBOOK_SECRET'] = os.environ.get('FACEBOOK_SECRET')
だから起動するには app.py 、次の環境変数を設定する必要があります。
FACEBOOK_SECRET={your secret} python app.py
Facebookのログインを処理する方法は次のとおりです。デフォルトでは、Satellizerはエンドポイントを呼び出します / auth / facebook 。
@app.route('/auth/facebook', methods=['POST']) def auth_facebook(): access_token_url = 'https://graph.facebook.com/v2.3/oauth/access_token' graph_api_url = 'https://graph.facebook.com/v2.5/me?fields=id,email' params = { 'client_id': request.json['clientId'], 'redirect_uri': request.json['redirectUri'], 'client_secret': app.config['FACEBOOK_SECRET'], 'code': request.json['code'] } # Exchange authorization code for access token. r = requests.get(access_token_url, params=params) # use json.loads instead of urlparse.parse_qsl access_token = json.loads(r.text) # Step 2. Retrieve information about the current user. r = requests.get(graph_api_url, params=access_token) profile = json.loads(r.text) # Step 3. Create a new account or return an existing one. user = User.query.filter_by(facebook_id=profile['id']).first() if user: return jsonify(token=user.token()) u = User(facebook_id=profile['id'], email=profile['email']) db.session.add(u) db.session.commit() return jsonify(token=u.token())
Facebookサーバーにリクエストを送信するには、便利なモジュールリクエストを使用します。これで、バックエンドの難しい部分が完了しました。フロントエンドでは、Facebookログインの追加は非常に簡単です。まず、Satellizerに FacebookのID このコードをに追加することによって app.config 関数:
$authProvider.facebook({ clientId: {your facebook app id}, // by default, the redirect URI is http://localhost:5000 redirectUri: 'http://localhost:5000/static/index.html' });
Facebookを使用してログインするには、次の電話をかけるだけです。
$auth.authenticate(“facebook”)
いつものように、あなたはチェックすることができます GitHubのコード
この時点で、webappは機能的に完成しています。ユーザーは、通常の電子メールとパスワードを使用するか、Facebookを使用してログイン/登録できます。ログインすると、ユーザーは自分の秘密のページを見ることができます。
現時点ではインターフェイスはあまりきれいではないので、ログインに失敗したときなどのエラーメッセージを適切に処理するために、レイアウト用のBootstrapと角度付きトースターモジュールを少し追加しましょう。
この美化部分のコードは見つけることができます ここに 。
この記事では、(単純な)AngularJSWebアプリへのSatellizerの段階的な統合について説明します。 Satellizerを使用すると、Twitter、Linkedinなどの他のソーシャルログインを簡単に追加できます。フロントエンドのコードは、記事とまったく同じです。ただし、ソーシャルネットワークSDKにはさまざまなプロトコルを持つさまざまなエンドポイントがあるため、バックエンドは異なります。 Facebook、Github、Google、Linkedin、Twiter、Bitbucketの例が含まれているhttps://github.com/sahat/satellizer/blob/master/examples/server/python/app.pyをご覧ください。疑わしい場合は、上のドキュメントを参照してください。 https://github.com/sahat/satellizer 。
関連: ブロックチェーンでワンクリックログイン:MetaMaskチュートリアル