Appearance
微信登录
微信登录是用户喜欢的登录方式,所以网站集成微信登录也是必备技能之一。
OAuth
测试帐号
使用测试帐号练习的目的是有些同学没有开放平台帐号。
首先需要配置微信公众号,然后配置 网页授权获取用户基本信息
然后配置授权回调页面域名,注意不要添加 http 前缀
登录流程
微信登录使用 OAuth 协议,具体操作步骤如下
- 引导用户访问微信服务器
- 用户决定是否授权网站授权
- 用户同意后返回到网站回调页面并传递code 授权码
- 网站根据授权码访问微信服务器申请获取access_token
- 网站使用获取的 access_token 获取用户资料
code 授权码
下面来体验微信登录的流程,首先登录微信开发者工具。
我们来首先来获取授权码
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
需要将地址中的以下参数进行替换
参数 | 说明 |
---|---|
appid | 测试号信息 appid |
redirect_uri | 授权码获取成功后的跳转地址 |
scope | 授权作用域 snsapi_base 或 snsapi_userinfo |
最终替换搂链接如下
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcxxxxxxx&redirect_uri=https://dev.hdcms.com/wechat&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
然后在微信开发者工具中访问该地址来获取 code 授权码,最后会在回调地址中看到 code 授权码,请进行复制后面会用到。
access_token
下面来通过上步中的 code 换取access_token,接口地址如下
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
需要将地址中的以下参数进行替换
参数 | 说明 |
---|---|
appid | 测试号信息 appid |
secret | 测试号信息 appsecret |
code | 上步中获取有 code 授权码 |
最后的地址类似如下
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxcf44xxxxxx&secret=6fd451c0cff05b6cxxxxxxx&code=011vR2300F5P5K1XNt300wpsMK3vR23O&grant_type=authorization_code
然后使用 postman 或 curl 命令访问上面请求地址来获取 access_token
用户资料
有了 access_token 后我们就可以来获取用户资料了,接口地址如下
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
需要将地址中的以下参数进行替换
参数 | 说明 |
---|---|
access_token | 上步中获取的 access_token |
然后在 postman 中访问地址获取用户资料
返回参数说明如下
参数 | 描述 |
---|---|
openid | 用户的唯一标识 |
nickname | 用户昵称 |
sex | 用户的性别,值为 1 时是男性,值为 2 时是女性,值为 0 时是未知 |
province | 用户个人资料填写的省份 |
city | 普通用户个人资料填写的城市 |
country | 国家,如中国为 CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640*640 正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像 URL 将失效。 |
privilege | 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) |
unionid | 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 |
开放平台
使用开放平台处理登录,可以将网站/小程序/App 等使用微信登录的用户,获取到统一的帐号。
使用微信登录网站需要先在微信开发平台进行配置,你可以访问[后盾人文档微信开放平台](https://doc.houdunren.com/tencent/3 开放平台.html) 学习怎么配置开发平台。
配置资料
在微信开放平台 管理中心>网站应用 中查看密钥资料
然后正确配置回调域,要求设置二级域名
编写代码
下面实现以开放平台完成网站登录的业务代码。
安装扩展
下面我们在 LARAVEL 框架的项目中集成微信登录。
laravel 为我们提供了方便的 [laravel/socialite](https://doc.houdunren.com/手册/laravel/10 官方扩展包/6 Socialite.html) 组件,同时也要安装 socialiteproviders/weixin-web 库
composer require laravel/socialite
composer require socialiteproviders/weixin-web
在 app/Providers/EventServiceProvider
中添加事件监听
protected $listen = [
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
'SocialiteProviders\\WeixinWeb\\WeixinWebExtendSocialite@handle',
],
];
配置
修改.env 配置文件
WECHATWEB_CLIENT_ID=wx9704xxxxx
WECHATWEB_CLIENT_SECRET=fc112xxxxxxxxxxx0c
WECHATWEB_REDIRECT_URI=https://dev.hdcms.com/login/wechat/callback
然后修改config/services.php
配置文件
'weixinweb' => [
'client_id' => env('WECHATWEB_CLIENT_ID'),
'client_secret' => env('WECHATWEB_CLIENT_SECRET'),
'redirect' => env('WECHATWEB_REDIRECT_URI')
],
配置项说明如下
配置 | 说明 |
---|---|
client_id | 开放平台网站应用中的 AppID |
client_secret | 开放平台网站应用中的 AppSecret |
redirect | 登录回调地址 |
控制器
我们来创建控制器实现业务代码
php artisan make:controller Auth/WeChatController
具体内容如下
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Socialite;
use App\Models\User;
use Auth;
class WeChatController extends Controller
{
/**
* 将用户重定向到授权页面
* @return \Illuminate\Http\Response
*/
public function redirectToProvider()
{
return Socialite::driver('weixinweb')->redirect();
}
/**
* 获取用户信息
* 下面有数据表操作,请根据你项目进行修改
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback()
{
$account = Socialite::driver('weixinweb')->user();
$unionid = $account->unionid ?? null;
if ($unionid) {
$user = User::where('unionid', $account->unionid)->first();
} else {
$user = User::where('openid', $account->getId())->first();
}
if (!$user) {
$user = User::create([
'avatar' => $account->user['headimgurl'],
'openid' => $account->getId(),
'unionid' => $unionid,
'name' => $account['nickname']
]);
Auth::login($user);
}
return redirect()->intended('/');
}
}
路由配置
下面来配置访问控制器的路由
Route::get('login/wechat', 'WeChatController@redirectToProvider');
Route::get('login/wechat/callback', 'WeChatController@handleProviderCallback');
登录测试
在浏览器中访问 https://dev.hdcms.com/login/wechat 就会看到登录二维码,扫码后就可以登录网站了。
Socialite::driver('weixinweb')->user()
得到的用户资料结果如下
SocialiteProviders\Manager\OAuth2\User {#1821 ▼
+accessTokenResponseBody: array:6 [▶]
+token: "36_MSfhsdpnY-f7D1laAqN9X5X8l8kMxxxxxxPN-ZpuqsJlB-oxnCaNZ9h--Fa6GocYrMyo"
+refreshToken: "36__wV-kvO5wUd5JoolfF1a8_XPExxxxxvz3mz4uxxxxQxxxxl0H4uJjYkQ"
+expiresIn: 7200
+id: "o4Cir0jmRruZWAKOKb4VB4mZO9s8"
+nickname: "向军"
+name: null
+email: null
+avatar: "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLia0aejribtQMzsP3SFiaSn3jCwgIQhrNGh9ibuuS3kWGJf4PxMbPGujWkVlYCKbdwpjrz38iaw4lNp0w/132"
+user: array:10 [▼
"openid" => "o4Cir0jmRruZWAKOxxxxxs8"
"nickname" => "向军"
"sex" => 1
"language" => "zh_CN"
"city" => "朝阳"
"province" => "北京"
"country" => "中国"
"headimgurl" => "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLia0aejribtQMzsP3SFiaSn3jCwgIQhrNGh9ibuuS3kWGJf4PxMbPGujWkVlYCKbdwpjrz38iaw4lNp0w/132"
"privilege" => []
"unionid" => "otxxt7Pm6jryw-xxxx4"
]
+"unionid": "otCIzxxxxxxw-SfOxxxujaxxx"
}
常见错误
redirect_uri 参数错误
登录微信开放平台 > 网站应用 > 开发信息 > 设置授权回调域
客户端登录
微信客户端登录指在微信 APP 内进行微信登录的操作。具体流程已经在上面的登录流程测试
部分讲解过。
实例开发中我们使用第三方扩展包可以提升开发效率,是推荐的解决方案。
安装扩展
下面我们在 LARAVEL 框架的项目中集成微信登录。
laravel 为我们提供了方便的laravel/socialite组件,同时也要安装socialiteproviders/weixin库
composer require laravel/socialite
composer require socialiteproviders/weixin
在app/Providers/EventServiceProvider
中添加事件监听
protected $listen = [
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
'SocialiteProviders\\Weixin\\WeixinExtendSocialite@handle',
],
];
配置
修改.env 配置文件
WECHATWEB_CLIENT_ID=wx9704xxxxx
WECHATWEB_CLIENT_SECRET=fc112xxxxxxxxxxx0c
WECHATWEB_REDIRECT_URI=https://dev.hdcms.com/login/wechat/callback
然后修改config/services.php
配置文件
'weixin' => [
'client_id' => env('WECHATWEB_CLIENT_ID'),
'client_secret' => env('WECHATWEB_CLIENT_SECRET'),
'redirect' => env('WECHATWEB_REDIRECT_URI')
],
配置项说明如下
配置 | 说明 |
---|---|
client_id | 微信公众号的 appID |
client_secret | 微信公众号的 appsecret |
redirect | 登录回调地址 |
控制器
我们来创建控制器
php artisan make:controller Auth/WeChatController
具体内容如下
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Socialite;
use App\Models\User;
use Auth;
class WeChatController extends Controller
{
/**
* 将用户重定向到授权页面
*
* @return \Illuminate\Http\Response
*/
public function redirectToProvider()
{
return Socialite::driver('weixin')->redirect();
}
/**
* 获取用户信息
* 下面有数据表操作,请根据你项目进行修改
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback()
{
$account = Socialite::driver('weixin')->user();
$unionid = $account->unionid ?? null;
if ($unionid) {
$user = User::where('unionid', $account->unionid)->first();
} else {
$user = User::where('openid', $account->getId())->first();
}
if (!$user) {
$user = User::create([
'avatar' => $account->user['headimgurl'],
'openid' => $account->getId(),
'unionid' => $unionid,
'name' => $account['nickname']
]);
Auth::login($user);
}
return redirect()->intended('/');
}
}
路由配置
下面来配置访问控制器的路由
Route::get('login/wechat', 'WeChatController@redirectToProvider');
Route::get('login/wechat/callback', 'WeChatController@handleProviderCallback');
登录测试
在微信客户端或微信开发者工具中访问 https://dev.hdcms.com/login/wechat 进行微信登录。
Socialite::driver('weixin')->user()
得到的用户资料结果如下
SocialiteProviders\Manager\OAuth2\User {#1821 ▼
+accessTokenResponseBody: array:6 [▶]
+token: "36_MSfhsdpnY-f7D1laAqN9X5X8l8kMxxxxxxPN-ZpuqsJlxxxxxxxxxxxxxxxxxxx"
+refreshToken: "36__wV-kvO5wUd5JoolfF1a8_XPExxxxxvz3mzxxxxxxxxxxxxxxxxxxxxx"
+expiresIn: 7200
+id: "o4Cir0jxxxxxxxxxxxxxxxx"
+nickname: "向军"
+name: null
+email: null
+avatar: "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLia0aejribtQMzsP3SFiaSn3jCwgIQhrxxxxxxxxxxxxxxxxxxxxx"
+user: array:10 [▼
"openid" => "o4Cxxxxxxxxxxxxxx"
"nickname" => "向军"
"sex" => 1
"language" => "zh_CN"
"city" => "朝阳"
"province" => "北京"
"country" => "中国"
"headimgurl" => "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLia0aejribtQMzsP3SFiaSn3jCwgIQhrNGh9ibuuxxxxxxxxxxxxx"
"privilege" => []
"unionid" => "otxxxxxxxxxxxxxx"
]
+"unionid": "otCIxxxxxxxxxxxxxxx"
}
常见错误
redirect_uri 参数错误
登录微信公众号(或测试公众号) > 接口权限表 > 网页帐号
然后设置授权回调页面域名
scope 参数错误或没有 scope 权限
这个问题和上面的情况差不多,是因为没有设置网页帐号的 授权回调域名
兼容操作
上面分别介绍了微信在网站与微信客户端的登录场景。其实我们可以通过判断设备来动态处理,而不需要写多个控制器与路径分别处理。
下面是微信客户端的检测函数
function is_wechat()
{
return isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false);
}
通过上面的函数判断后来使用不同的驱动即可。