You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.7 KiB

3 days ago
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\WechatUser;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException;
class H5WechatController extends Controller
{
/**
* 公众号网页授权 code 换用户信息,并签发 Sanctum 令牌WechatUser
*/
public function oauth(Request $request): JsonResponse
{
$data = $request->validate([
'code' => ['required', 'string'],
]);
$appId = (string) config('wechat.app_id');
$secret = (string) config('wechat.app_secret');
if ($appId === '' || $secret === '') {
return response()->json(['message' => '服务端未配置微信公众号 AppId/AppSecret'], 503);
}
$tokenRes = Http::timeout(15)
->get('https://api.weixin.qq.com/sns/oauth2/access_token', [
'appid' => $appId,
'secret' => $secret,
'code' => $data['code'],
'grant_type' => 'authorization_code',
])
->json();
if (! empty($tokenRes['errcode'])) {
throw ValidationException::withMessages([
'code' => [$tokenRes['errmsg'] ?? '微信 code 无效或已使用'],
]);
}
$accessToken = (string) ($tokenRes['access_token'] ?? '');
$openid = (string) ($tokenRes['openid'] ?? '');
if ($accessToken === '' || $openid === '') {
return response()->json(['message' => '微信未返回 access_token'], 422);
}
$unionid = $tokenRes['unionid'] ?? null;
$info = Http::timeout(15)
->get('https://api.weixin.qq.com/sns/userinfo', [
'access_token' => $accessToken,
'openid' => $openid,
'lang' => 'zh_CN',
])
->json();
if (! empty($info['errcode'])) {
$info = [];
}
if ($unionid === null && ! empty($info['unionid'])) {
$unionid = $info['unionid'];
}
$wu = WechatUser::query()->updateOrCreate(
['openid' => $openid],
[
'unionid' => $unionid,
'nickname' => $info['nickname'] ?? null,
'avatar_url' => $info['headimgurl'] ?? null,
]
);
$plain = $wu->createToken('wechat-h5')->plainTextToken;
return response()->json([
'token' => $plain,
'user' => [
'id' => $wu->id,
'nickname' => $wu->nickname,
'avatar_url' => $wu->avatar_url,
],
]);
}
}