appid = env("CUSTOMER_APPID"); $this->appsecret = env("CUSTOMER_APPSECRET"); $this->authModel = new Customer(); } /** * Create a new AuthController instance. * * @return void */ public function guard() { return auth()->guard($this->guardName); } public function guardName() { return $this->guardName; } /** * Get a JWT via given credentials. * * @return \Illuminate\Http\JsonResponse */ /** * @OA\Post( * path="/customer/login", * tags={"用户端用户相关"}, * summary="V2-通过用户名和密码登录", * description="预留接口,用户测试账号密码登录。实际场景使用code换取openid进行登录", * @OA\Parameter(name="username", in="query", @OA\Schema(type="string"), required=true, description="用户名"), * @OA\Parameter(name="password", in="query", @OA\Schema(type="string"), required=true, description="密码"), * @OA\Response( * response="200", * description="登录接口" * ) * ) */ public function login() { $credentials = request(['username', 'password']); if (!$token = $this->guard()->attempt($credentials)) { return response()->json([ 'errorcode' => '401', 'errormsg' => '登录失败' ], 401); } return $this->respondWithToken($token); } /** * @OA\Post( * path="/customer/login-by-code", * tags={"用户端用户相关"}, * summary="V2-通过微信端获取的code进行登录", * description="", * @OA\Parameter(name="code", in="query", @OA\Schema(type="string"), required=true, description="code"), * @OA\Response( * response="200", * description="微信code登录接口" * ) * ) */ public function loginByCode() { $code = request()->code; $url = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"; $url = sprintf($url, $this->appid, $this->appsecret, $code); $res = curl($url); if (!isset($res["openid"])) { return response()->json($res, 401); } $openid = $res["openid"]; $user = $this->authModel->firstOrNew([ "openid" => $openid ]); if ($user->mobile) { $token = $this->guard()->login($user); return $this->respondWithToken($token); } $user->session_key = $res["session_key"]; return response()->json([ 'token' => null, 'user_info' => $user ]); } /** * @OA\Post( * path="/customer/me", * tags={"用户端用户相关"}, * summary="V2-通过token换取个人信息", * description="", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="通过token换取个人信息" * ) * ) */ public function me() { return response()->json($this->guard()->user()); } /** * Log the user out (Invalidate the token). * * @return \Illuminate\Http\JsonResponse */ public function logout() { $this->guard()->logout(); return response()->json(['message' => 'Successfully logged out']); } /** * Refresh a token. * * @return \Illuminate\Http\JsonResponse */ public function refresh() { return $this->respondWithToken($this->guard()->refresh()); } /** * Get the token array structure. * * @param string $token * * @return \Illuminate\Http\JsonResponse */ protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => $this->guard()->factory()->getTTL() * 60, 'user_info' => $this->guard()->user() ]); } public function getAccessToken() { $access_token = cache('customer_access_token'); if (!$access_token) { $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; $url = sprintf($url, $this->appid, $this->appsecret); $callback = curl($url); if (!isset($callback['access_token'])) { dd("获取ACCESS_TOKEN失败,请重试!"); } $access_token = $callback['access_token']; Cache::put("customer_access_token", $access_token, 60); } return $access_token; } /** * @OA\Post( * path="/customer/get-phone-by-openid", * tags={"用户端用户相关"}, * summary="V2-通过openid,encryptedData,iv获取手机号", * description="", * @OA\Parameter(name="openid", in="query", @OA\Schema(type="string"), required=true, description="openid"), * @OA\Parameter(name="iv", in="query", @OA\Schema(type="string"), required=true, description="iv"), * @OA\Parameter(name="encryptedData", in="query", @OA\Schema(type="string"), required=true, description="encryptedData"), * @OA\Response( * response="200", * description="通过openid,encryptedData,iv获取手机号" * ) * ) */ public function getPhoneByOpenid() { $encryptedData = request()->encryptedData; $sessionKey = request()->sessionKey; $iv = request()->iv; $aesKey = base64_decode($sessionKey); $aesIV = base64_decode($iv); $aesCipher = base64_decode($encryptedData); $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); Log::channel("get_mobile_by_openid")->info($result); $dataObj = json_decode($result); if ($dataObj == NULL) { return response()->json([ 'errorcode' => '4001', 'errormsg' => "手机号码解密失败" ], 401); } if ($dataObj->watermark->appid != $this->appid) { return response()->json([ 'errorcode' => '4002', 'errormsg' => 'APPID不匹配' ], 401); } $openid = request()->openid; $user = $this->authModel->firstOrCreate([ "mobile" => $dataObj->phoneNumber ]); $user->openid = $openid; $user->save(); $token = $this->guard()->login($user); return $this->respondWithToken($token); } /** * @OA\Post( * path="/customer/mobile", * tags={"用户端用户相关"}, * summary="V2-通过code获取手机号", * description="", * @OA\Parameter(name="code", in="query", @OA\Schema(type="string"), required=true, description="code"), * @OA\Parameter(name="openid", in="query", @OA\Schema(type="string"), required=true, description="openid"), * @OA\Response( * response="200", * description="" * ) * ) */ public function mobile() { $code = request('code'); $openid = request()->openid; // if (empty($openid)) { // return response()->json([ // 'errorcode' => '4001', // 'errormsg' => "openid为空" // ], 401); // } // $config = [ // 'app_id' => $this->appid, // 'secret' => $this->appsecret // ]; $url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" . $this->getAccessToken(); $postData = json_encode(['code' => $code]); $result = curl($url, $postData); $mobile = ''; if (isset($result['phone_info']['pure_phone_number'])) { $mobile = $result['phone_info']['pure_phone_number']; } elseif (isset($result['phone_info']['purePhoneNumber'])) { $mobile = $result['phone_info']['purePhoneNumber']; } if (empty($mobile)) { return response()->json([ 'errorcode' => '4001', 'errormsg' => "手机号码解密失败" ], 401); } $user = $this->authModel->firstOrCreate([ "mobile" => $mobile ]); $user->openid = $openid; $user->save(); $token = $this->guard()->login($user); return $this->respondWithToken($token); } }