This commit is contained in:
尖叫 2023-10-27 16:06:22 +08:00
parent e07f755b33
commit b865ea6e9a
2 changed files with 256 additions and 2 deletions

View File

@ -150,8 +150,47 @@ class AuthController extends Controller
$data = $form->login();
$this->lock->release();
return $this->responseHandler($data);
}
}
/**
* showdoc
* @catalog 登录注册
* @title 微信小程序登录
* @description 本接口提供微信登录
* @method post
* @url /api/auth/login-by-wxoa
* @param code 必选 string wx.login() 获取 临时登录凭证code
* @return {"code":0,"msg":"ok","data":{"access_token":"WXl0dXlzbDhxcTdTcExyQUVmVWRoLzV6cnJrK04rV1RocHVpTzdGTWxRajhLVzA3Vk9hWEhBPT0=","refresh_token":"aDcxQTc4ZDFtUGlWOEh6akUwaVVQQ2NuZGNxdTJhcDQ5cGxSZll6Mk9PWUJPdmhRQU1RMW5DWDl1SFllVFZrbWVvU1JCWEdOSUl2S29rU3I3NndobWVTN0kxNlhjSFhwODREYlRFUkFmZVhUNUpQZHkxd1oveWlnOVdQa2JzSHp6K1dZS1dtRVJBSzFwMnBnVnNmdncvRTgvWDRiSWhpUA==","access_token_expires":1592392165,"refresh_token_expires":1594976965}}
* @return_param access_token string 登录令牌
* @return_param access_token_expires int 登录令牌失效时间
* @return_param refresh_token string 刷新token令牌
* @return_param refresh_token_expires int 刷新token令牌失效时间
* @remark
*/
public function actionLoginByWxoa()
{
if(!\Yii::$app->request->isPost){
$data = $this->invaildRequest();
return $this->responseHandler($data);
}
if(!$this->lock->acquire()){
$data = ['code' => 1, 'msg' => '系统繁忙!稍后再试^v^!'];
return $this->responseHandler($data);
}
$form = new LoginByWxmpForm();
$form->attributes = \Yii::$app->request->post();
$form->cx_mch_id = $this->cx_mch_id;
$form->token_type = $this->_cx_token_type;
$form->wechat_mp = $this->wechat_mp;
$data = $form->login();
$this->lock->release();
return $this->responseHandler($data);
}
/**
* showdoc
* @catalog 登录注册

View File

@ -0,0 +1,215 @@
<?php
/**
* @author Any
* @description KISS
* @date 2020-12-3
* @version 1.0.0
*
* _____LOG_____
*
*/
namespace app\modules\api\models;
use app\models\User;
use app\components\auth\AToken;
use app\components\wechat\aes\WxBizDataCrypt;
use app\models\UserOauth;
use app\models\common\CommonUserEditForm;
use app\components\SysConst;
use app\components\FlashStorage;
class LoginByWxoaForm extends ApiModel
{
public $code;
public $code_expires;//code是否过期0=否1=是
public $cx_mch_id;
public $token_type;
public $wechat_mp;
public function rules()
{
return [
[['code'], 'trim'],
[['code'], 'string'],
[['code_expires'], 'integer'],
[['code', 'token_type', 'wechat_mp'], 'required'],
];
}
public function login()
{
if (!$this->validate()) {
return $this->getModelError();
}
$res = FlashStorage::getCache("m{$this->cx_mch_id}_c{$this->code}");
if ($this->code_expires == 1 || $res === false) {
$res = $this->code2session($this->code);
if ($res['code'] != 0)
return $res;
FlashStorage::setCache("m{$this->cx_mch_id}_c{$this->code}", $res, 864000);
}
$session_key = $res['data']['session_key'];
$openid = $res['data']['openid'];
$unionid = isset($res['data']['unionid']) ? $res['data']['unionid'] : null;
$res = $this->decrypted_data($session_key);
if ($res['code'] != 0) {
return $res;
}
$decrypted_info = json_decode($res['data'], true);
$openid = $openid ? $openid : $decrypted_info['openId'];
$nickname = $decrypted_info['nickName'];
$avatar_url = empty($decrypted_info['avatarUrl']) ? User::DEFAULT_AVATAR_URL : $decrypted_info['avatarUrl'];
$gender = $decrypted_info['gender'];
if ($unionid == null) {
$unionid = isset($decrypted_info['unionId']) ? $decrypted_info['unionId'] : '0';
}
//用户是否存在
$user_oauth = null;
if ($unionid != 0) {
//优选使用unionid
$user_oauth = UserOauth::findOne([
'cx_mch_id' => $this->cx_mch_id,
'is_delete' => 0,
'unionid' => $unionid
]);
}
if ($user_oauth == null) {
$user_oauth = UserOauth::findOne([
'cx_mch_id' => $this->cx_mch_id,
'is_delete' => 0,
'type' => SysConst::$cxOauthProviderWxmp,
'openid' => $openid
]);
}
$t = \Yii::$app->db->beginTransaction();
if ($user_oauth != null) {
//用户是否存在
$user = User::findOne([
'id' => $user_oauth->user_id,
'is_delete' => 0,
'cx_mch_id' => $this->cx_mch_id,
'status' => User::STATUS_NORMAL
]);
if ($user == null) {
\Yii::error("[LoginByWxmpForm] 用户(ID:{$user_oauth->user_id})不存在");
return [
'code' => 1,
'msg' => '系统内部异常,请联系管理员'
];
}
} else {
$form = new CommonUserEditForm();
$form->scenario = 'wxmp_signup';
$form->model = new User();
$form->cx_mch_id = $this->cx_mch_id;
$form->username = User::generateUsername(3, "wx", 6);
$form->nickname = $nickname;
$form->avatar_url = $avatar_url;
$form->access_token = \Yii::$app->security->generateRandomString();
$form->gender = $gender;
$form->is_modify_un = 1;
$res = $form->save();
if ($res['code'] != 0)
return $res;
$user = $form->model;
$user_oauth = new UserOauth();
$user_oauth->cx_mch_id = $this->cx_mch_id;
$user_oauth->type = SysConst::$cxOauthProviderWxmp;
$user_oauth->user_id = $user->id;
$user_oauth->openid = $openid;
$user_oauth->unionid = $unionid;
$user_oauth->is_delete = 0;
$user_oauth->created_at = time();
}
//更新用户信息
$user_oauth->nickname = $nickname;
$user_oauth->avatar_url = $avatar_url;
if ($unionid !== 0 && $user_oauth->unionid == 0) {
$user_oauth->unionid = $unionid;
}
if (!$user_oauth->save()) {
$t->rollBack();
return $this->getModelError($user_oauth);
}
if (!\Yii::$app->user->login($user)) {
$t->commit();
return [
'code' => 1,
'msg' => '登录失败'
];
}
$args = [];
$args['cx_mch_id'] = $this->cx_mch_id;
$args['token_type'] = $this->token_type;
$atoken = new AToken($args);
$data = $atoken->generate_access_token();
if ($data['code'] == 0) {
$err_msg = "微信小程序登录成功";
User::lastLogin($user->id, 1, $err_msg, $this->cx_mch_id);
}
$t->commit();
//是否需要绑定
$data = User::bindQuery($user_oauth->user, $data);
return $data;
}
/***
* 用户数据解密
*/
private function decrypted_data($session_key)
{
$pc = new WxBizDataCrypt($this->wechat_mp->appId, $session_key);
$errCode = $pc->decryptData($this->encrypted_data, $this->iv, $data);
if ($errCode == 0) {
return [
'code' => 0,
'msg' => 'success',
'data' => $data
];
} else {
return [
'code' => 1,
'msg' => $errCode,
];
}
}
private function code2session($code)
{
$api = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->wechat_mp->appId}&secret={$this->wechat_mp->appSecret}&code=" . $code . "&grant_type=authorization_code";
$this->wechat_mp->curl->get($api);
if ($this->wechat_mp->curl->error_code != 0) {
return [
'code' => 1,
'msg' => "err_code:{$this->wechat_mp->curl->error_code}err_msg:{$this->wechat_mp->curl->error_msg}"
];
}
$resp = $this->wechat_mp->curl->response;
$res = json_decode($resp, true);
if (!isset($res['access_token']) || !isset($res['openid'])) {
return [
'code' => 1,
'msg' => isset($res['errmsg']) ? $res['errmsg'] : 'error'
];
}
return [
'code' => 0,
'msg' => 'ok',
'data' => $res
];
}
}