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.

241 lines
7.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\Customer;
use App\Customer;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
use Tymon\JWTAuth\Facades\JWTAuth;
class AuthController extends Controller
{
public $guardName = "customer";
public $appid;
public $appsecret;
public $authModel;
public function __construct()
{
$this->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-通过openidencryptedDataiv获取手机号",
* 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="通过openidencryptedDataiv获取手机号"
* )
* )
*/
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);
$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);
}
}