Login.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkAdmin
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://demo.thinkadmin.top
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // +----------------------------------------------------------------------
  11. // | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
  12. // | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
  13. // +----------------------------------------------------------------------
  14. namespace app\api\controller;
  15. use AlibabaCloud\Client\AlibabaCloud;
  16. use AlibabaCloud\Client\Exception\ClientException;
  17. use AlibabaCloud\Client\Exception\ServerException;
  18. use app\api\controller\Base;
  19. use think\Db;
  20. use Firebase\JWT\JWT;
  21. use EasyWeChat\Factory;
  22. /**
  23. * @title 登录
  24. * @controller Login
  25. * @group worker
  26. */
  27. class Login extends Base
  28. {
  29. /**
  30. * @title 用户协议
  31. * @desc 用户协议
  32. * @author QGF
  33. * @url /api/Login/agreement
  34. * @method GET
  35. * @tag 用户协议
  36. * @return name:-- type:string default:-- desc:用户协议内容(富文本)
  37. */
  38. public function agreement(){
  39. $this->success('获取成功',htmlspecialchars_decode(sysconf('agreement')));
  40. }
  41. /**
  42. * @title 隐私政策
  43. * @desc 隐私政策
  44. * @author QGF
  45. * @url /api/Login/privacy_policy
  46. * @method GET
  47. * @tag 隐私政策
  48. * @return name:-- type:string default:-- desc:隐私政策
  49. */
  50. public function privacy_policy(){
  51. $this->success('获取成功',htmlspecialchars_decode(sysconf('privacy_policy')));
  52. }
  53. /**
  54. * @title 注册
  55. * @desc 注册
  56. * @author QGF
  57. * @url /api/Login/register
  58. * @method POST
  59. * @tag 注册
  60. * @param name:phone type:int require:1 default:-- desc:手机号
  61. * @param name:code type:int require:1 default:-- desc:短信验证码
  62. * @param name:password type:string require:1 default:-- desc:密码
  63. */
  64. public function register(){
  65. $phone = input('phone');
  66. $code = input('code');
  67. $password = input('password');
  68. if(empty($phone) || empty($code) || empty($password)){
  69. $this ->error('参数错误');
  70. }
  71. $sms_id = $this->verify_sms($phone,$code);
  72. if(empty($sms_id)){
  73. $this->error('验证码不正确');
  74. }
  75. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  76. if(empty($member_id)){
  77. $this->error('该手机号已被注册');
  78. }
  79. $data = array(
  80. 'phone'=>$phone,
  81. 'password' => md5($password),
  82. 'decode_password' => $password,
  83. 'name' => substr($phone,-4),
  84. 'headimg' => 'http://pic.gujiafuwu.com/0909a49add201291/a20687c6493d3eab.jpg',
  85. );
  86. Db::name('store_member')->insert($data);
  87. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  88. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  89. $token = self::create_jwt($member_id);
  90. $this->success('注册成功',$token);
  91. }
  92. /**
  93. * @title 微信登录(小程序)
  94. * @desc 微信登录(小程序)
  95. * @author QGF
  96. * @url /api/Login/we_chat_login
  97. * @method POST
  98. * @tag 登录 授权
  99. * @param name:code type:int require:1 default:-- desc:code值
  100. * @param name:headimg type:string require:1 default:-- desc:头像地址
  101. * @param name:name type:string require:1 default:-- desc:昵称
  102. * @return name:openid type:string default:-- desc:用户openid(未绑定手机号)
  103. * @return name:headimg type:string default:-- desc:用户头像地址(未绑定手机号)
  104. * @return name:name type:string default:屈耀光 desc:用户昵称(未绑定手机号)
  105. * @return name:token type:string default:-- desc:用户登录成功后的token值(已绑定手机号)
  106. */
  107. public function we_chat_login(){
  108. $code = input('code');
  109. $headimg = input('headimg');
  110. $name = input('name');
  111. if(empty($code) || empty($headimg) || empty($name)){
  112. $this->error('参数错误');
  113. }
  114. $app = Factory::miniProgram(config('app.mini_program'));
  115. $data = $app->auth->session($code);
  116. if(empty($data['openid'])){
  117. $this->error('微信登录失败');
  118. }
  119. $member = Db::name('store_member')->field('id,phone')->where('openid',$data['openid'])->find();
  120. if(empty($member['phone'])){
  121. $member_data = array(
  122. 'openid' => $data['openid'],
  123. 'headimg' => $headimg,
  124. 'name' => $name
  125. );
  126. $this->success('授权成功',$member_data);
  127. }
  128. $uid = $member['id'];
  129. if(empty($uid)){
  130. $this->error('数据有误');
  131. }
  132. $token = self::create_jwt($uid);
  133. $this->success('登录成功',$token);
  134. }
  135. /**
  136. * @title 微信登录(app)
  137. * @desc 微信登录
  138. * @author QGF
  139. * @url /api/Login/we_chat_app
  140. * @method POST
  141. * @tag 登录 授权
  142. * @param name:code type:int require:1 default:oRZeJ55dhq8y6gHI9PVwCrv0gvSM desc:code值
  143. * @return name:-- type:json default:-- desc:微信注册返回授权后的信息(openid:微信openid,name:微信昵称,headimgurl:微信头像地址,token:token值(这时为空)注:仅微信注册有)
  144. * @return name:token type:string default:-- desc:用户微信登录成功后的token值(仅用户登录有)
  145. */
  146. public function we_chat_app(){
  147. $code = input('code');
  148. if(empty($code)){
  149. $this->error('参数错误');
  150. }
  151. $res = requestGet('https://api.weixin.qq.com/sns/oauth2/access_token?appid='.config('app_program')['app_id'].'&secret='.config('app_program')['secret'].'&code='.$code.'&grant_type=authorization_code');
  152. $res = json_decode($res,true);
  153. $user_info = requestGet('https://api.weixin.qq.com/sns/userinfo?access_token='.$res['access_token'].'&openid='.$res['openid']);
  154. $user_info = json_decode($user_info,true);
  155. $data['openid'] = $user_info['openid'];
  156. $data['name'] = $user_info['nickname'];
  157. $data['headimg'] = $user_info['headimg'];
  158. $data['token'] = '';
  159. $member_id = Db::name('store_member')->where('app_openid',$data['openid'])->value('id');
  160. if(empty($member_id)){
  161. $this->success('授权成功',$data);
  162. }else{
  163. $token = self::create_jwt($member_id);
  164. $data['token'] = $token;
  165. $this->success('登录成功',$data);
  166. }
  167. }
  168. /**
  169. * @title 验证码登录(app端)
  170. * @desc 验证码登录
  171. * @author QGF
  172. * @url /api/Login/verification_code_login
  173. * @method POST
  174. * @tag 登录
  175. * @param name:phone type:int require:1 default:18263693516 desc:手机号
  176. * @param name:code type:int require:1 default:123456 desc:短信验证码
  177. * @return name:token type:string default:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMsImlzcyI6Imh0dHBzOlwvXC96YWluLmNvbSIsImF1ZCI6Imh0dHBzOlwvXC96YWluLmNvbSIsImlhdCI6MTYxNzc3NDUxMSwibmJmIjoxNjE3Nzc0NTExLCJleHAiOjE2MjAzNjY1MTF9.FNvIuz6axfzIhicStWx8SqNfBlyaSbUflmV2gV3EBzI desc:用户登录成功后的token值(已绑定手机号)
  178. */
  179. public function verification_code_login(){
  180. $code = input('code');
  181. $phone = input('phone');
  182. if(empty($code) || empty($phone)){
  183. $this->error('参数错误');
  184. }
  185. $sms_id = $this->verify_sms($phone,$code);
  186. if(empty($sms_id)){
  187. $this->error('验证码不正确');
  188. }
  189. $worker_id = Db::name('store_worker')->where('phone',$phone)->value('id');
  190. if(!$worker_id){
  191. $data = array(
  192. 'phone'=>$phone,
  193. 'name' => substr($phone,-4),
  194. 'headimg' => 'http://pic.gujiafuwu.com/0909a49add201291/a20687c6493d3eab.jpg',
  195. 'worker_promise' => '8,'
  196. );
  197. Db::name('store_worker')->insert($data);
  198. $worker_id = Db::name('store_worker')->where('phone',$phone)->value('id');
  199. }
  200. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  201. $token = self::create_jwt($worker_id);
  202. Db::name('store_worker')->where('id',$worker_id)->update(array('token'=>$token));
  203. $this->success('登录成功',$token);
  204. }
  205. /**
  206. * @title 绑定手机号(点击微信登录时还没注册,绑定完手机号提交信息去注册)
  207. * @desc 绑定手机号
  208. * @author QGF
  209. * @url /api/Login/binding_phone
  210. * @method POST
  211. * @tag 绑定手机号
  212. * @param name:platform type:1 require:1 default:1 desc:平台(注:1:小程序2:app)
  213. * @param name:phone type:int require:1 default:18263693516 desc:要绑定的手机号
  214. * @param name:code type:int require:1 default:123456 desc:短信验证码
  215. * @param name:openid type:string require:1 default:oRZeJ55dhq8y6gHI9PVwCrv0gvSM desc:微信授权返回的openid
  216. * @param name:name type:string require:1 default:屈耀光 desc:微信授权返回的用户昵称
  217. * @param name:headimg type:string require:1 default:https://thirdwx.qlogo.cn/mmopen/vi_32/r6iajx0fibpet9P7tRz5Xiag2Gia05eEjX08RaIPykkicsMDtpaWKqb23jibnBgibGQqgZ9yW7wWR6QG7ajRQp3BrLzfA/132 desc:微信授权返回的用户头像地址
  218. * @return name:token type:string default:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMsImlzcyI6Imh0dHBzOlwvXC96YWluLmNvbSIsImF1ZCI6Imh0dHBzOlwvXC96YWluLmNvbSIsImlhdCI6MTYxNzc3NDUxMSwibmJmIjoxNjE3Nzc0NTExLCJleHAiOjE2MjAzNjY1MTF9.FNvIuz6axfzIhicStWx8SqNfBlyaSbUflmV2gV3EBzI desc:绑定成功后的token值
  219. */
  220. public function binding_phone(){
  221. $phone = input('phone');
  222. $code = input('code');
  223. $openid = input('openid');
  224. $name = input('name');
  225. $headimg = input('headimg');
  226. $platform = input('platform',1); //1:小程序,2:app
  227. if(empty($phone) || empty($code) || empty($openid) || empty($name) || empty($headimg)){
  228. $this ->error('参数错误');
  229. }
  230. $sms_id = $this->verify_sms($phone,$code);
  231. if(empty($sms_id)){
  232. $this->error('验证码不正确');
  233. }
  234. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  235. if(!$member_id){
  236. $data = array(
  237. 'phone'=>$phone,
  238. 'name' => $name,
  239. 'headimg' => $headimg,
  240. );
  241. if($platform == 1){
  242. $data['openid'] = $openid;
  243. }else{
  244. $data['app_openid'] = $openid;
  245. }
  246. Db::name('store_member')->insert($data);
  247. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  248. }else{
  249. if($platform == 1){
  250. $update_data['openid'] = $openid;
  251. }else{
  252. $update_data['app_openid'] = $openid;
  253. }
  254. Db::name('store_member')->where('id',$member_id)->update($update_data);
  255. }
  256. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  257. $token = self::create_jwt($member_id);
  258. $this->success('注册成功',$token);
  259. }
  260. /**
  261. * @title 发送短信验证码
  262. * @desc 发送短信验证码
  263. * @author QGF
  264. * @url /api/Login/send_sms
  265. * @method POST
  266. * @tag 短信验证码
  267. * @param name:phone type:int require:1 default:18263693516 desc:要获取验证码的手机号
  268. * @return name:code type:string default:123456 desc:验证码
  269. */
  270. public function send_sms(){
  271. $phone = input('phone');
  272. if(empty($phone)){
  273. $this ->error('参数错误');
  274. }
  275. $code = rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
  276. AlibabaCloud::accessKeyClient('LTAI5tF4i8gTzxgP2pybHWdo', 'r0YxVLtsPfUl71Etp74sOHuckSwYaZ')->regionId('cn-hangzhou')->asDefaultClient();
  277. try {
  278. $result = AlibabaCloud::rpc()
  279. ->product('Dysmsapi')
  280. ->version('2017-05-25')
  281. ->action('SendSms')
  282. ->method('POST')
  283. ->host('dysmsapi.aliyuncs.com')
  284. ->options([
  285. 'query' => [
  286. 'RegionId' => "cn-hangzhou",
  287. 'PhoneNumbers' => $phone,
  288. 'SignName' => "玺悦学府",
  289. 'TemplateCode' => "SMS_215725390",
  290. 'TemplateParam' => json_encode(array("code"=>$code)),
  291. ],
  292. ])->request();
  293. $result = $result->toArray();
  294. $sms_data = array(
  295. 'phone'=>$phone,
  296. 'code'=>$code,
  297. 'result'=>$result['Message']
  298. );
  299. Db::name('store_member_sms')->insert($sms_data);
  300. } catch (ClientException $e) {
  301. echo $e->getErrorMessage() . PHP_EOL;
  302. } catch (ServerException $e) {
  303. echo $e->getErrorMessage() . PHP_EOL;
  304. }
  305. $this->success('发送成功');
  306. }
  307. //校验短信验证码
  308. public function verify_sms($phone = '',$code = ''){
  309. $store_member_sms = Db::name('store_member_sms')->field('id,code')->where('phone',$phone)->where('used',0)->order('id desc')->find();
  310. if($store_member_sms['code'] == $code){
  311. return $store_member_sms['id'];
  312. }else{
  313. return 0;
  314. }
  315. }
  316. //token加密
  317. public function create_jwt($workerId)
  318. {
  319. $key = md5(config('app.jwt')); //jwt的签发密钥,验证token的时候需要用到
  320. $time = time(); //签发时间
  321. $expire = $time + config('app.jwt_time'); //过期时间
  322. $token = array(
  323. "wid" => $workerId,
  324. "iss" => "https://zain.com",//签发组织
  325. "aud" => "https://zain.com", //签发作者
  326. "iat" => $time,
  327. "nbf" => $time,
  328. "exp" => $expire
  329. );
  330. $jwt = JWT::encode($token, $key);
  331. return $jwt;
  332. }
  333. }