今日、PC であれ携帯電話であれ、サードパーティのログインの使用は非常に一般的です。多目的に利用できる特徴があるため、どのようなWebサイトやソフトウェアであっても、このサードパーティログイン機能があれば、再度登録手順を踏む必要はなく、そのままログインすることができます。サードパーティのアカウントを使用すると便利ですよね。プログラム開発で重要なのはユーザーエクスペリエンスであり、ユーザーにとって「小さくてもすべての機能が備わった」使いやすい製品を作ることが私たちの責任です。それでは、Restful API にサードパーティ ログインを実装するにはどうすればよいでしょうか? Segmentfault では希望する答えが見つかりませんでしたが、最終的には実装アイデアを書き留めました。もちろん、これは私の実装方法の 1 つにすぎません。誰かがより良い方法を持っている場合は、喜んで書きます。通信する。 。
1. Restful API アーキテクチャを使用して、QQ、WeChat ログインなどのサードパーティ ログインを実装します。
1. user テーブルと user_login テーブルの 2 つのテーブルを作成します。 user テーブルについては詳しく説明しません。ここでは user_login テーブルに焦点を当てます。 user_login テーブルのフィールド:
id iduser_id 用户idtype 登录类型(如:QQ,weixin) qq_access_token QQ授权access_tokenqq_openid QQ openidwx_access_token 微信授权access_tokenwx_openid 微信openid
Weibo や Taobao などの他のサードパーティ ログインがある場合は、上記のルールに従って対応するフィールドを追加するだけです。
2. gii によって生成される UserLogin.php モデルは次のとおりです。
<?phpclass UserLogin extends /yii/db/ActiveRecord{ /** * @inheritdoc */ public static function tableName() { return 'user_login'; } /** * @inheritdoc */ public function rules() { return [ [['user_id'], 'integer'], [['type'], 'string', 'max' => 30], [['qq_access_token', 'wx_access_token'], 'string', 'max' => 220], [['qq_openid', 'wx_openid'], 'string', 'max' => 100] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => Yii::t('yii', 'ID'), 'user_id' => Yii::t('yii', 'User ID'), 'type' => Yii::t('yii', 'Type'), 'qq_access_token' => Yii::t('yii', 'Qq Access Token'), 'qq_openid' => Yii::t('yii', 'Qq Openid'), 'wx_access_token' => Yii::t('yii', 'Wx Access Token'), 'wx_openid' => Yii::t('yii', 'Wx Openid'), ]; } }
3. コントローラー内のメソッドは次のとおりです。 QQ ログイン
public function actionQqLogin() { $_model = new UserLogin(); $model = new TUser(); $post = Yii::$app->request->post(); if(!empty($post)) { $t_nickname = !empty($post['t_nickname']) ? trim($post['t_nickname']) : ''; $access_token = !empty($post['access_token']) ? trim($post['access_token']) : ''; $openid = !empty($post['openid']) ? trim($post['openid']) : ''; $t_photo = !empty($post['t_photo']) ? trim($post['t_photo']) : '';//头像 $res = UserLogin::find() ->where(['type'=>'qq','qq_openid'=>$openid]) ->one(); //判断是否已存在用户信息,存在则返回该条用户信息 if(!empty($res)) { $res->qq_access_token = $access_token; $res->save(); //获取一条用户信息 $user = $model->getUserrow($res->user_id); if(!empty($user)){ return $user; }else{ ErrorMsg::Info(Yii::t('yii','Login fail')); } }else{ //保存新用户 $user = $this->saveUser($t_nickname,$t_nickname,$openid,'','',$t_photo); if(empty($return['error_code'])){ $_model->user_id = $user->t_id; $_model->type = 'qq'; $_model->qq_access_token = $access_token; $_model->qq_openid = $openid; $_model->save(); $user = $model->getUserrow($user->t_id); //保证返回数据字段一致 } return $user; } }else{ ErrorMsg::Info(Yii::t('yii','Login fail')); } }
WeChat ログイン
public function actionWxLogin() { $_model = new UserLogin(); $model = new TUser(); $post = Yii::$app->request->post(); if(!empty($post)) { $t_nickname = !empty($post['t_nickname']) ? trim($post['t_nickname']) : ''; $access_token = !empty($post['access_token']) ? trim($post['access_token']) : ''; $openid = !empty($post['openid']) ? trim($post['openid']) : ''; $t_photo = !empty($post['t_photo']) ? trim($post['t_photo']) : '';//头像 $res = UserLogin::find() ->where(['type'=>'weixin','wx_openid'=>$openid]) ->one(); //判断是否已存在用户信息,存在则返回该条用户信息 if(!empty($res)) { $res->wx_access_token = $access_token; $res->save(); //获取一条用户信息 $user = $model->getUserrow($res->user_id); if(!empty($user)){ return $user; }else{ ErrorMsg::Info(Yii::t('yii','Login fail')); } }else{ //保存新用户 $user = $this->saveUser($t_nickname,$t_nickname,$openid,'','',$t_photo); if(empty($return['error_code'])){ $_model->user_id = $user->t_id; $_model->type = 'weixin'; $_model->wx_access_token = $access_token; $_model->wx_openid = $openid; $_model->save(); $user = $model->getUserrow($user->t_id);//保证返回数据字段一致 } return $user; } }else{ ErrorMsg::Info(Yii::t('yii','Login fail')); } }
ユーザー情報を保存する方法:
public function saveUser($t_username,$t_nickname,$openid,$email,$phone,$t_photo) { $access_token = sha1(time().$openid); $data = array( "t_nickname"=> $t_nickname, "t_password"=> base64_encode($openid), "t_state" => 0, "t_photo" => $t_photo?$t_photo:"/images/upload/100x100/no_photo.jpg", "t_timezone"=> "PRC", "t_language"=> "zh_cn", "access_token"=> $access_token, "rent_user_type"=>"3", 't_add_time'=>time(), ); $model = new $this->modelUser; $model->attributes = $data; if(!empty($t_nickname) && !empty($openid)){ if(!$model->save()){ ErrorMsg::Info(Yii::t('yii','Reg fail')); } return $model; }else{ ErrorMsg::Info(Yii::t('yii','m-log-2')); } }
TUser モデルでのサードパーティのログインによる基本的なユーザー情報の取得方法:
public function getUserrow($uid) { $user = $this->find() ->select(['access_token','t_password']) ->where(['t_id'=>$uid]) ->one(); if(!empty($user)){ $result['access_token']= !empty($access_token=$user->access_token)?$access_token:""; $result['appsercert'] = !empty($t_password=$user->t_password)?$t_password:""; return $result; //返回给手机端用,只返回access_token和appsercert。 } }
さて、Restful API アーキテクチャが登場しました。サードパーティ ログインが実装されました。Weibo や Taobao などのサードパーティ ログインを実装するという考え方も同じです。つまり、改善しても大丈夫です。受信パラメータ。これは、Restful API アーキテクチャのサードパーティ ログインを実装するための私のアイデアです。十分ではない提案があれば、良い提案をして、一緒にコミュニケーションしましょう。
1. QQ と weixin の type、openid、access_token フィールドを直接追加するこのアプローチは、将来さらに追加する場合、拡張性が低くなります。例: Weibo 、タオバオなどのサードパーティ ログインでユーザー テーブルを操作する必要がある場合、ユーザー テーブルの操作が頻繁すぎると問題が発生しやすく、すべてのユーザーがサードパーティ ログインを使用するわけではないため、大量の空き地と廃棄物。 user_login テーブルを独自に作成した理由は、これらの考慮事項に基づいています。 2. すべてのユーザー情報を携帯電話に返します。実際には、モバイル端末はこれらを必要とせず、access_token と appercert の 2 つのフィールドをモバイル端末に返すだけでよく、モバイル端末は自らユーザー情報を取得します。