laravel 微信登陆
2018年11月12日在写微信登陆之前你可以先看看微信网页授权登陆原理,和laravel jwt-auth的使用,和本站api原生登陆
1. 安装 socialiteproviders
1 |
$ composer require socialiteproviders/weixin |
打开app/Providers/EventServiceProvider.php
添加事件
1 2 3 4 5 6 7 8 9 10 11 12 |
. . . protected $listen = [ #添加事件,这个事件是包里面的 \SocialiteProviders\Manager\SocialiteWasCalled::class => [ 'SocialiteProviders\Weixin\WeixinExtendSocialite@handle' ], ]; . . . |
打开config/services.php
添加配置
1 2 3 4 5 6 7 8 9 10 |
. . . 'weixin' => [ 'client_id' => env('WEIXIN_KEY'), 'client_secret' => env('WEIXIN_SECRET'), 'redirect' => env('WEIXIN_REDIRECT_URI'), #这个是跳转的链接 ], ]; |
打开.env
添加配置
1 2 3 |
WEIXIN_KEY=wx935f74c981701499 WEIXIN_SECRET=90a76604490641777ea7b42052557cc1 WEIXIN_REDIRECT_URI= |
测试是否配置正确,请将$code
里面的值换成你的值,如果不知道$code
怎么获取请看微信网页授权登陆原理
1 2 3 4 5 6 7 |
$ php artisan tinker $code = '081JlqCb07T3Uu1k02Bb0w7sCb0JlqCc'; $driver = Socialite::driver('weixin'); $response = $driver->getAccessTokenResponse($code); $driver->setOpenId($response['openid']); $oauthUser = $driver->userFromToken($response['access_token']); |
2.功能开发创建数据库
1 |
$ php artisan make:migration add_weixin_openid_to_users_table --table=users |
打开databases/migrations/< your_date >_add_weixin_openid_to_users_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddWeixinOpenidToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('weixin_openid')->unique()->nullable()->after('password'); $table->string('weixin_unionid')->unique()->nullable()->after('weixin_openid'); $table->string('password')->nullable()->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('weixin_openid'); $table->dropColumn('weixin_unionid'); $table->string('password')->nullable(false)->change(); }); } } |
1 |
$ php artisan migrate |
3.功能开发创建路由
打开routes\api.php
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php use Illuminate\Http\Request; $api = app('Dingo\Api\Routing\Router'); $api->version('v1', ['namespace' => 'App\Http\Controllers\Api'], function ($api) { #定义了一个命名空间 $api->group(['middleware' => 'api.throttle', 'limit' => config('api.rate_limits.sign.limit'), 'expires' => config('api.rate_limits.sign.expires')], function ($api) { #定义了请求次数 $api->post('socials/{social_type}/authorizations', 'AuthorizationsController@socialStore') ->name('api.socials.authorizations.store'); #第三方登陆 }); }); |
4.功能开发创建控制器和验证类
1 2 |
$ php artisan make:controller Api/AuthorizationsController $ php artisan make:request Api/SocialAuthorizationRequest |
编写验证类app/Http/Requests/Api/SocialAuthorizationRequest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace App\Http\Requests\Api; use Dingo\Api\Http\FormRequest; class SocialAuthorizationRequest extends FormRequest { public function authorize() { return true; } /** * 一方多用,如果给了code和access_token就走第一个,如果是微信和open_id 就走第二个 * @return array */ public function rules() { $rules = [ 'code' => 'required_without:access_token|string', 'access_token' => 'required_without:code|string', ]; if ($this->social_type == 'weixin' && !$this->code) { $rules['openid'] = 'required|string'; } return $rules; } } |
编辑控制类app/Http/Controllers/Api/AuthorizationsController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?php namespace App\Http\Controllers\Api; use Auth use App\Models\User; use Illuminate\Http\Request; use App\Http\Requests\Api\SocialAuthorizationRequest; class AuthorizationsController extends Controller { /** * 第三方登陆 * @param $type * @param SocialAuthorizationRequest $request * @return mixed */ public function socialStore($type, SocialAuthorizationRequest $request) { if (!in_array($type, ['weixin'])) { #判断第三方登陆,我们这里是否开通 return $this->response->errorBadRequest(); #直接返回请求错误 } $driver = \Socialite::driver($type); #选择第三方登陆类型 /** * 尝试获取用户信息 */ try { if ($code = $request->code) { #如果请求里面有code证明是用code来获取用户信息 $response = $driver->getAccessTokenResponse($code); #开始请求 $token = array_get($response, 'access_token'); #从数组中获取access_token } else { #否则就是用token和openId来获取用户信息的 $token = $request->access_token; #获取请求的请求access_token if ($type == 'weixin') { #判断类型是否是微信 $driver->setOpenId($request->openid); #设置openId } } $oauthUser = $driver->userFromToken($token); #获取用户信息 } catch (\Exception $e) { return $this->response->errorUnauthorized('参数错误,未获取用户信息'); } switch ($type) { case 'weixin': $unionid = $oauthUser->offsetExists('unionid') ? $oauthUser->offsetGet('unionid') : null; #判断微信id是否是公共id if ($unionid) { #如果是公共id $user = User::where('weixin_unionid', $unionid)->first(); #绑定公共id的字段 } else { #否则 $user = User::where('weixin_openid', $oauthUser->getId())->first(); #如果没有公共id绑定open_id } // 没有用户,默认创建一个用户 if (!$user) { $user = User::create([ 'name' => $oauthUser->getNickname(), #创建一个名字 'avatar' => $oauthUser->getAvatar(), #创建一个头像 'weixin_openid' => $oauthUser->getId(), #绑定open_id 'weixin_unionid' => $unionid, #绑定公共id ]); } break; } $token = Auth::guard('api')->fromUser($user); #根据用户信息开始登陆 return $this->respondWithToken($token); } /** * 返回用户数据的方法 * @param $token * @return mixed */ protected function respondWithToken($token) { return $this->response->array([ 'access_token' => $token, 'token_type' => 'Bearer', 'expires_in' => \Auth::guard('api')->factory()->getTTL() * 60 ]); } } |
测试一下