微信公众号网页开发中,EasyWechat + laravel5.5 auth实现授权注册账号,自动登录
安装auth:
php artisan make:auth
安装easywechat:
composer require "overtrue/laravel-wechat:~4.0"
创建easywechat配置文件:
php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"
添加wechat.oauth中间件:
app/Http/Kernel.php中,
protected $routeMiddleware = [
'wechat.oauth' => \Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate::class, ];
假设我们的网站域名是www.auth.com
//中间件 mock.user是为了开发时不调用微信授权虚拟的数据,对应的用户是openid为12345的用户,如果不是开发环境需要把这个中间件去掉
Route::group(['middleware' => 'mock.user'], function () {//这个中间件可以先忽略,我们稍后再说
Route::middleware('wechat.oauth:snsapi_base')->group(function () {
Route::get('/login', 'SelfAuthController@autoLogin')->name('login');
});
Route::middleware('wechat.oauth:snsapi_userinfo')->group(function () {
Route::get('/register', 'SelfAuthController@autoRegister')->name('register');
});
});
Route::get('/', function () {
return view('welcome');
});
Route::group(['middleware' => 'auth'], function () {
Route::get('/example', 'ExampleController@example');
});
给login路由配置wechat.oauth:snsapi_base中间件,它是静默获取的,不需要用户授权,并且只会获取用户的openid。
给register路由配置’wechat.oauth:snsapi_userinfo中间件,它会重定向到微信授权页,需要用户授权,可以获取到用户的nickname,头像等信息。
给/example路由配置的是auth中间件,如果用户未登陆,它会重定向到命名为login的路由。
这其实是我们自己创建的一个中间件,可以虚拟一个微信用户,在开发过程中,我们不必真的去请求微信的信息,所有的信息都通过这个中间件来虚拟。
namespace App\Http\Middleware;
use Closure;
use Overtrue\Socialite\User as SocialiteUser;
class MockUser {
public function handle($request, Closure $next) {
$user = new SocialiteUser([
'id' => '12345',//openid
'name' => 'mock',
'nickname' => 'mock user',
'avatar' => '',
'email' => null,
'original' => [],
'provider' => 'WeChat',
]);
session(['wechat.oauth_user.default' => $user]);
return $next($request);
}
}
注册中间件
protected $routeMiddleware = [
'mock.user' => \App\Http\Middleware\MockUser::class, ];
namespace App\Http\Controllers;
use App\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
class SelfAuthController extends Controller {
public function getEasyWechatSession() {
$user = session('wechat.oauth_user.default');
return $user;
}
public function autoLogin() {
$userInfo = $this->getEasyWechatSession();
$openId = $userInfo['id'];
//查看对应的openid是否已被注册
$userModel = User::where('openid', $openId)->first();
//如果未注册,跳转到注册
if (!$userModel) {
return redirect()->route('register');
} else {
//如果已被注册,通过openid进行自动认证,
//认证通过后重定向回原来的路由,这样就实现了自动登陆。
if(Auth::attempt(['openid' => $openId, 'password' => ‘123456'])) { return redirect()->intended(); } } } public function autoRegister() { $userInfo = $this->getEasyWechatSession(); //根据微信信息注册用户。 $userData = [ 'password' => bcrypt(’123456'),
'openid' => $userInfo['id'],
'nickname' => $userInfo['nickname'],
];
//注意批量写入需要把相应的字段写入User中的$fillable属性数组中
User::create($userData);
return redirect()->route('login');
}
}
好,假设我们在此网站没有注册过,那么当我们访问www.auth.com/example时,会发生下面事情:
1).因为/example路由在auth中间件包裹下,所以我们会被重定向到命名为login的路由下,注意命名一词。
2).因为login路由在wechat.oauth:snsapi_base中间件的包裹下,所以会静默获取用户微信的openid,该信息可以通过session(‘wechat.oauth_user.default’)获取,通过openid查询users表,发现没有此条记录,也就是没有注册过,就会跳转到命名为register的路由下。
3).因为register路由在wechat.oauth:snsapi_userinfo中间件的包裹下,所以会跳转到微信授权页面,用户授权后,重定向回register,此时可以通过session(‘wechat.oauth_user.default’)获取用户的微信信息,根据微信信息向users表中写入数据,即注册用户。注册成功后重定向到命名为login的路由下。
4).因为用户已经注册过,所以通过openid可以查询到对应的users表信息,然后使用Auth::attempt([‘openid’ => $openId, ‘password’ => ‘123456’]);对用户进行认证。认证成功后,重定向到我们之前访问的路由www.auth.com/example,在example方法中,我们可以使用Auth::user()获取users表中的信息
如果我们在此网站注册过,那么当我们访问www.auth.com/example时,如果session没过期,我们可以直接访问,如果session过期,那么会重新走一边login逻辑,register逻辑不会再走。
参考文献:
1.easywechat:https://github.com/overtrue/laravel-wechat
2.laravel5.5手册:https://laravel-china.org/docs/laravel/5.5/authentication#08b509
3.微信公众号开发手册:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842