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.

508 lines
14 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\appapi\controller\v1;
use app\appapi\ApiController;
use think\facade\Db;
// use think\facade\Session;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Log;
use Firebase\JWT\JWT as FireJWT;
use Firebase\JWT\Key as FireKey;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
// use Lcobucci\JWT\Parser;
// use thans\jwt\exception\JWTException;
// use thans\jwt\exception\TokenBlacklistException;
// use thans\jwt\exception\TokenBlacklistGracePeriodException;
// use thans\jwt\exception\TokenExpiredException;
// use thans\jwt\exception\TokenInvalidException;
// use thans\jwt\facade\JWTAuth;
use GuzzleHttp\Client;
// use app\common\lib\Vcard;
// use app\common\lib\Aes;
use app\common\lib\Sign;
use app\common\lib\Token;
use app\common\Utils;
use app\common\sms\Sms;
use \asc\line\LineLogin;
class Auth extends ApiController
{
public function login(){
$token = JWTAuth::builder(
[
'user_id' => 270,
'user_name' => 'wayne',
]
);
return $this->success(['token'=>'Bearer '.$token]);
}
public function checkLogin(){
try{
$payload = JWTAuth::auth(false);
return $this->Success(true);
} catch (TokenInvalidException $e){
return $this->Success(false);
} catch (\Exception $e){
return $this->Success(false);
}
}
/**
* return 200 成功
* 201 不是會員
*/
public function lineLogin(){
$id_token = input('token');
if(!$id_token){
return $this->Error('請求參數錯誤');
}
$line_res = LineLogin::verifyIdToken(env('line.login_channel_id'), $id_token);
if(!$line_res){
return $this->Error('發生錯誤,請重新執行',401);
}
$user=Db::name('users')
->where('line_id',$line_res['sub'])
->find();
if(!$user){ //第一次登入,請求註冊
return $this->success('非會員',201);
}
$token = JWTAuth::builder(
[
'user_id' => $user['user_id'],
'user_name' => $user['user_name'],
]
);
return $this->success(['token'=>'Bearer '.$token]);
}
public function lineReg(){
$id_token = input('id_token');
$mobile = input('mobile');
//驗證id_token
$line_res = LineLogin::verifyIdToken(env('line.login_channel_id'), $id_token);
if(!$line_res){
return $this->Error('發生錯誤,請重新執行',401);
}
//檢查line id是否己經是會員
//TODO
$user=Db::name('users')
->where('line_id',$line_res['sub'])
->find();
if($user){
return $this->error('已是會員,重新登入',501);
}
$data = [
'line_id' => $line_res['sub'],
'line_picture' => $line_res['picture'],
'line_name' => $line_res['name'],
'user_name' => $mobile,
'mobile_phone' => $mobile,
'refer_code' => $this->getReferCode(),
'reg_time' => time()
];
//檢查mobile phone是否己經是會員
//TODO
$user=Db::name('users')
->where('mobile_phone',$mobile)
->find();
if($user){
//update
$rtn = Db::name('users')
->where('mobile_phone',$mobile)
->update($data);
}else{
//推薦人代碼
$data['parent_id'] = 1;
//insert
$id = Db::name('users')
->insertGetId($data);
}
$user=Db::name('users')
->where('line_id',$line_res['sub'])
->find();
if(!$user){
return $this->success('註冊失敗,請重新操作',502);
}
$token = JWTAuth::builder(
[
'user_id' => $user['user_id'],
'user_name' => $user['user_name'],
]
);
return $this->success(['token'=>'Bearer '.$token]);
$avatar=$this->saveLineImage($data['line_picture'],$data['user_id']);
$data['line_picture']= getUrl().'/storage/'.$data['user_id'].'/'.$avatar;
if(!isset($data['avatar'])){
$data['avatar']=$data['line_picture'];
}else{
$file_path = $_SERVER['DOCUMENT_ROOT'].'/storage/'.$data['user_id'].'/'.date('Ymd').'/';
if(!is_dir($file_path)){
mkdir($file_path, 0777, true);
}
$temp_file = str_replace(getUrl(),"",$data['avatar']);
$avatar_file = $file_path.basename($temp_file);
if(!rename($_SERVER['DOCUMENT_ROOT'].$temp_file, $avatar_file)){
return $this->error('搬移檔案失敗');
}
$data['avatar']=getUrl().'/storage/'.$data['user_id'].'/'.date('Ymd').'/'.basename($temp_file);
}
try{
$id = Db::name('user')
->insertGetId($data);
$refer_code = encodeRefer($id);
$result = Db::name('user')
->where('id',$id)
->update(['code'=>$refer_code]);
$qrcodeUrl = genQrCode('https://'.$_SERVER['HTTP_HOST'].'/home/?aid='.$agent['prefix'],$data['user_id'],'refer');
$aes = new Aes([]);
$params = urlencode($aes->encrypt('user_id='.$data['user_id'].'&verify_code='.input('verify')));
$nfcUrl = genQrCode('https://'.$_SERVER['HTTP_HOST'].'/card/?params='.$params,$data['user_id'],'nfc');
Vcard::genVcf($data['user_id']);
$token = JWTAuth::builder(
[
'id' => $id,
'user_id' => $data['user_id'],
'level' => 0
]);
if($action == 'openright'){
Db::name('precard')
->where('verify_code',input('verify'))
->update(['status'=>2]);
}
return $this->success(['uid'=>$data['user_id'],'token'=>'Bearer'.$token]);
}catch(\Exception $e){
return $this->error('註冊失敗');
}
}
/**
* 註冊會員
*/
public function register(){
$data = input('post.');
unset($data['version']);
unset($data['controller']);
unset($data['action']);
unset($data['uid']);
unset($data['userid']);
unset($data['refer_code']);
unset($data['verify']);
unset($data['token']);
unset($data['type']);
$data=array_map('asc_trim',$data);
if(input('type')=='line'){
//驗證id_token
$verify_line = $this->verifyIdToken(input('token'));
if(!isset($verify_line)){
return $this->error('id token expire',500);
}
$data['line_name'] = $verify_line['name'];
$data['line_picture'] = $verify_line['picture'];
$data['line_id'] = $verify_line['sub'];
$data['mobile_phone'] = $data['phone'];
$user_data = [
'line_id' => $data['line_id'],
'line_name' => $data['line_name'],
'line_picture' => $data['line_picture'],
];
}else{
$data['mobile_phone'] = input('token');
}
$data['real_name'] = $data['name'];
//新增User至Oss Server
$user_data['appid'] = 'sc';
$user_data['phone'] = $data['mobile_phone'];
$user_data['real_name'] = $data['real_name'];
$user_data['email'] = $data['email'];
$user_data['timestamp'] = time();
//檢查refer_code是否存在存在則加入user_data
if(strlen(input('refer_code'))>0){
$user_data['refer_code'] = input('refer_code');
}
$sign = Sign::genSign($user_data);
$user_data['sign'] = $sign;
$client = new Client([
'base_uri' => 'https://sso.slash1000.com/api/v1/'
]);
$response = $client->post('user/add',[
'form_params' => $user_data
]);
if($response->getStatusCode()!=200){
return $this->error('上傳SSO SERVER 失敗');
}
$sso_data = json_decode($response->getBody()->getContents(),true)['data'];
try{
//檢查相同電話的會員是否已存在
$data=[
'sso_user_id' => $sso_data['info']['user_id'],
'headimg' => $sso_data['info']['avatar'],
'line_id' => isset($sso_data['info']['line_id'])?$sso_data['info']['line_id']:'',
'line_name' => isset($sso_data['info']['line_name'])?$sso_data['info']['line_name']:'',
'line_picture' => isset($sso_data['info']['line_picture'])?$sso_data['info']['line_picture']:'',
'mobile_phone' => $sso_data['info']['phone'],
'user_name' => $sso_data['info']['phone'],
'real_name' => $sso_data['info']['real_name'],
'refer_code' => $sso_data['info']['code'],
'parent_id' => $sso_data['info']['parent_id'],
'reg_time' => time(),
'last_login' => time(),
];
$is_exist = Db::name('users')->where('mobile_phone',$sso_data['info']['phone'])->count();
if($is_exist>0){
//更新會員資料
Db::name('users')
->where('mobile_phone',$sso_data['info']['phone'])
->update($data);
}else{
$id = Db::name('users')
->insertGetId($data);
}
$payload = [
'user_id' => $data['sso_user_id'],
];
$token = Token::genToken($payload);
return $this->success(['uid'=>$data['sso_user_id'],'token'=>'Bearer '.$token]);
}catch(\Exception $e){
return $this->error($e->getMessage());
}
}
public function bindCard(){
$uid = input('uid');
$verify = input('verify');
try{
Db::name('user')
->where('user_id',$uid)
->update(['uniqid'=>$verify]);
Db::name('precard')
->where('verify_code',$verify)
->update(['status'=>2]);
return $this->success('綁定成功');
}catch(\Exception $e){
return $this->error('綁定失敗');
}
}
public function checkLineId(){
$line_id=input('lineid');
$user = Db::name('user')
->where('line_id',$line_id)
->find();
if($user){
return $this->error('會員已存在');
}
return $this->success('檢查成功');
}
private function verifyIdToken($token){
try{
$client = new Client();
$response = $client->request('POST', 'https://api.line.me/oauth2/v2.1/verify', [
'form_params' => [
'id_token' => $token,
'client_id'=> env('line.login_channel_id')
]
]);
$body = $response->getBody()->getContents();
return json_decode($body, true);
} catch (\Exception $e) {
// print_r($e);
return false;
}
}
private function saveLineImage($pictureUrl,$uid)
{
if($pictureUrl){
$curl = curl_init($pictureUrl);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
$imageData=curl_exec($curl);
curl_close($curl);
$filename=$uid."_line.jpg";
$filedir=$_SERVER['DOCUMENT_ROOT'].'/storage/'.$uid;
if (!file_exists($filedir)) {
mkdir($filedir , 0777 , true);
}
$fp=fopen($filedir.'/'.$filename,'a');
fwrite($fp,$imageData);
fclose($fp);
return $filename;
}else{
return false;
}
}
public function uploadAvatar(){
$files = request()->file('file');
$savename = \think\facade\Filesystem::disk('public')->putFile( 'temp' , $files);
$avatar = getUrl().'/storage/'.$savename;
// Db::name('user')
// ->where('user_id',input('user_id'))
// ->update(['avatar'=>$avatar]);
return $this->Success($avatar);
}
public function sendVerify(){
$username = input('username');
//在這裡檢查是否已經發送過驗證碼,如果已經發送過,則不再發送
$is_exist = Cache::get($username);
// if ($is_exist) {
// // 驗證碼存在
// return $this->error('驗證碼已發送,請勿重複發送');
// } else {
// 驗證碼不存在或已過期
// 重新生成驗證碼並存儲到Redis中
$verification_code = mt_rand(100000, 999999);
Cache::set($username, $verification_code, 300);
$message = '[SlashCard]'.$verification_code.'簡訊登入驗證碼請於5分鐘內輸入驗證碼完成登入。';
// 發送短信
Sms::createSms('smsking',
[
'recipient'=>$username,
'message'=>$message
]);
return $this->success('驗證碼已發送,請注意查收');
// }
}
private function lineAuth($code)
{
if(strlen($code)){
$oline=new LineLogin('1657776252','de34ab10e249e5c874b81d04ddc6e41d');
$response=$oline->getLineToken($code);
print_r($response);
$user_profile = $oline->getUserProfile($response['access_token']);
$res = $user_profile;
return $res;
}else{
return false;
}
}
private function addLineUser($user){
$data = [
'line_id' => $user['line_id'],
'line_picture' => $user['picture'],
'line_name' => $user['name'],
'user_name' => $user['line_id'],
'password' => '',
'reg_time' => time()
];
}
private function getReferCode(){
$refer = Utils::genReferCode();
$rtn = Db::name('users')
->where('refer_code',$refer)
->count();
if($rtn){
$refer = $this->getReferCode();
}
return $refer;
}
}