Login.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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/register
  46. * @method POST
  47. * @tag 注册
  48. * @param name:phone type:int require:1 default:-- desc:手机号
  49. * @param name:code type:int require:1 default:-- desc:短信验证码
  50. * @param name:password type:string require:1 default:-- desc:密码
  51. */
  52. public function register(){
  53. $phone = input('phone');
  54. $code = input('code');
  55. $password = input('password');
  56. if(empty($phone) || empty($code) || empty($password)){
  57. $this ->error('参数错误');
  58. }
  59. $sms_id = $this->verify_sms($phone,$code);
  60. if(empty($sms_id)){
  61. $this->error('验证码不正确');
  62. }
  63. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  64. if(!empty($member_id)){
  65. $this->error('该手机号已被注册');
  66. }
  67. $data = array(
  68. 'phone'=>$phone,
  69. 'password' => md5($password),
  70. 'decode_password' => $password,
  71. 'name' => substr($phone,-4),
  72. 'headimg' => 'https://zjth2021.oss-cn-beijing.aliyuncs.com/0909a49add201291/a20687c6493d3eab.jpg',
  73. 'background' => Db::name('store_background')->where('id',1)->value('logo'),
  74. );
  75. Db::name('store_member')->insert($data);
  76. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  77. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  78. $token = self::create_jwt($member_id);
  79. $this->success('注册成功',$token);
  80. }
  81. /**
  82. * @title 微信登录(小程序)
  83. * @desc 微信登录(小程序)
  84. * @author QGF
  85. * @url /api/Login/we_chat_login
  86. * @method POST
  87. * @tag 登录 授权
  88. * @param name:code type:int require:1 default:-- desc:code值
  89. * @param name:headimg type:string require:1 default:-- desc:头像地址
  90. * @param name:name type:string require:1 default:-- desc:昵称
  91. * @return name:openid type:string default:-- desc:用户openid(未绑定手机号)
  92. * @return name:headimg type:string default:-- desc:用户头像地址(未绑定手机号)
  93. * @return name:name type:string default:屈耀光 desc:用户昵称(未绑定手机号)
  94. * @return name:token type:string default:-- desc:用户登录成功后的token值(已绑定手机号)
  95. */
  96. public function we_chat_login(){
  97. $code = input('code');
  98. $headimg = input('headimg');
  99. $name = input('name');
  100. if(empty($code) || empty($headimg) || empty($name)){
  101. $this->error('参数错误');
  102. }
  103. $app = Factory::miniProgram(config('app.mini_program'));
  104. $data = $app->auth->session($code);
  105. if(empty($data['openid'])){
  106. $this->error('微信登录失败');
  107. }
  108. $member = Db::name('store_member')->field('id,phone')->where('openid',$data['openid'])->find();
  109. if(empty($member['phone'])){
  110. $member_data = array(
  111. 'openid' => $data['openid'],
  112. 'headimg' => $headimg,
  113. 'name' => $name
  114. );
  115. $this->success('授权成功',$member_data);
  116. }
  117. $uid = $member['id'];
  118. if(empty($uid)){
  119. $this->error('数据有误');
  120. }
  121. $token = self::create_jwt($uid);
  122. $this->success('登录成功',$token);
  123. }
  124. /**
  125. * @title 微信登录(app)
  126. * @desc 微信登录
  127. * @author QGF
  128. * @url /api/Login/we_chat_app
  129. * @method POST
  130. * @tag 登录 授权
  131. * @param name:code type:int require:1 default:oRZeJ55dhq8y6gHI9PVwCrv0gvSM desc:code值
  132. * @return name:-- type:json default:-- desc:微信注册返回授权后的信息(openid:微信openid,name:微信昵称,headimgurl:微信头像地址,token:token值(这时为空)注:仅微信注册有)
  133. * @return name:token type:string default:-- desc:用户微信登录成功后的token值(仅用户登录有)
  134. */
  135. public function we_chat_app(){
  136. $code = input('code');
  137. if(empty($code)){
  138. $this->error('参数错误');
  139. }
  140. $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');
  141. $res = json_decode($res,true);
  142. var_dump($res);exit();
  143. $user_info = requestGet('https://api.weixin.qq.com/sns/userinfo?access_token='.$res['access_token'].'&openid='.$res['openid']);
  144. $user_info = json_decode($user_info,true);
  145. $data['openid'] = $user_info['openid'];
  146. $data['name'] = $user_info['nickname'];
  147. $data['headimg'] = $user_info['headimg'];
  148. $data['token'] = '';
  149. $member_id = Db::name('store_member')->where('app_openid',$data['openid'])->value('id');
  150. if(empty($member_id)){
  151. $this->success('授权成功',$data);
  152. }else{
  153. $token = self::create_jwt($member_id);
  154. $data['token'] = $token;
  155. $this->success('登录成功',$data);
  156. }
  157. }
  158. /**
  159. * @title 密码登录
  160. * @desc 密码登录
  161. * @author QGF
  162. * @url /api/Login/password_login
  163. * @method POST
  164. * @tag 密码登录
  165. * @param name:phone type:int require:1 default:-- desc:手机号
  166. * @param name:password type:string require:1 default:-- desc:密码
  167. * @return name:token type:string default:-- desc:用户登录成功后的token值
  168. */
  169. public function password_login(){
  170. $phone = input('phone');
  171. $password = input('password');
  172. if(empty($password) || empty($phone)){
  173. $this->error('参数错误');
  174. }
  175. $member_id = Db::name('store_member')->where('phone',$phone)->where('password',md5($password))->value('id');
  176. if(empty($member_id)){
  177. $this->error('手机号或密码错误');
  178. }
  179. $token = self::create_jwt($member_id);
  180. $this->success('登录成功',$token);
  181. }
  182. /**
  183. * @title 绑定手机号(点击微信登录时还没注册,绑定完手机号提交信息去注册)
  184. * @desc 绑定手机号
  185. * @author QGF
  186. * @url /api/Login/binding_phone
  187. * @method POST
  188. * @tag 绑定手机号
  189. * @param name:platform type:1 require:0 default:1 desc:平台(注:1:小程序2:app)
  190. * @param name:phone type:int require:1 default:-- desc:要绑定的手机号
  191. * @param name:code type:int require:1 default:-- desc:短信验证码
  192. * @param name:openid type:string require:1 default:-- desc:微信授权返回的openid
  193. * @param name:name type:string require:1 default:-- desc:微信授权返回的用户昵称
  194. * @param name:headimg type:string require:1 default:-- desc:微信授权返回的用户头像地址
  195. * @return name:token type:string default:-- desc:绑定成功后的token值
  196. */
  197. public function binding_phone(){
  198. $phone = input('phone');
  199. $code = input('code');
  200. $openid = input('openid');
  201. $name = input('name');
  202. $headimg = input('headimg');
  203. $platform = input('platform',1); //1:小程序,2:app
  204. if(empty($phone) || empty($code) || empty($openid) || empty($name) || empty($headimg)){
  205. $this ->error('参数错误');
  206. }
  207. $sms_id = $this->verify_sms($phone,$code);
  208. if(empty($sms_id)){
  209. $this->error('验证码不正确');
  210. }
  211. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  212. if(!$member_id){
  213. $data = array(
  214. 'phone'=>$phone,
  215. 'name' => $name,
  216. 'headimg' => $headimg,
  217. );
  218. if($platform == 1){
  219. $data['openid'] = $openid;
  220. }else{
  221. $data['app_openid'] = $openid;
  222. }
  223. Db::name('store_member')->insert($data);
  224. $member_id = Db::name('store_member')->where('phone',$phone)->value('id');
  225. }else{
  226. if($platform == 1){
  227. $update_data['openid'] = $openid;
  228. }else{
  229. $update_data['app_openid'] = $openid;
  230. }
  231. Db::name('store_member')->where('id',$member_id)->update($update_data);
  232. }
  233. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  234. $token = self::create_jwt($member_id);
  235. $this->success('注册成功',$token);
  236. }
  237. /**
  238. * @title 忘记密码
  239. * @desc 忘记密码
  240. * @author QGF
  241. * @url /api/Login/reset_password
  242. * @method POST
  243. * @tag 忘记密码
  244. * @param name:phone type:int require:1 default:-- desc:手机号
  245. * @param name:code type:int require:1 default:-- desc:短信验证码
  246. * @param name:password type:string require:1 default:-- desc:密码
  247. */
  248. public function reset_password(){
  249. $phone = input('phone');
  250. $code = input('code');
  251. $password = input('password');
  252. if(empty($phone) || empty($code) || empty($password)){
  253. $this ->error('参数错误');
  254. }
  255. $sms_id = $this->verify_sms($phone,$code);
  256. if(empty($sms_id)){
  257. $this->error('验证码不正确');
  258. }
  259. $member = Db::name('store_member')->field('id,decode_password')->where('phone',$phone)->find();
  260. if(empty($member['id'])){
  261. $this ->error('该手机号未注册');
  262. }
  263. if($password == $member['decode_password']){
  264. $this ->error('新密码与原密码一致,直接登录');
  265. }
  266. $update_data = array(
  267. 'password'=>md5($password),
  268. 'decode_password'=>$password
  269. );
  270. Db::name('store_member')->where('phone',$phone)->update($update_data);
  271. Db::name('store_member_sms')->where('id',$sms_id)->update(array('used'=>1));
  272. $this->success('修改密码成功');
  273. }
  274. /**
  275. * @title 发送短信验证码
  276. * @desc 发送短信验证码
  277. * @author QGF
  278. * @url /api/Login/send_sms
  279. * @method POST
  280. * @tag 短信验证码
  281. * @param name:phone type:int require:1 default:-- desc:要获取验证码的手机号
  282. * @return name:code type:string default:-- desc:验证码
  283. */
  284. public function send_sms(){
  285. $phone = input('phone');
  286. if(empty($phone)){
  287. $this ->error('参数错误');
  288. }
  289. $code = rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
  290. AlibabaCloud::accessKeyClient('LTAI5tDNASTjwM9mDSGckY3N', 'nAKY40GjGz4hf5A9RpoffDmaYWNL3y')->regionId('cn-hangzhou')->asDefaultClient();
  291. try {
  292. $result = AlibabaCloud::rpc()
  293. ->product('Dysmsapi')
  294. ->version('2017-05-25')
  295. ->action('SendSms')
  296. ->method('POST')
  297. ->host('dysmsapi.aliyuncs.com')
  298. ->options([
  299. 'query' => [
  300. 'RegionId' => "cn-hangzhou",
  301. 'PhoneNumbers' => $phone,
  302. 'SignName' => "碳汇资产",
  303. 'TemplateCode' => "SMS_222240090",
  304. 'TemplateParam' => json_encode(array("code"=>$code)),
  305. ],
  306. ])->request();
  307. $result = $result->toArray();
  308. $sms_data = array(
  309. 'phone'=>$phone,
  310. 'code'=>$code,
  311. 'result'=>$result['Message']
  312. );
  313. Db::name('store_member_sms')->insert($sms_data);
  314. } catch (ClientException $e) {
  315. echo $e->getErrorMessage() . PHP_EOL;
  316. } catch (ServerException $e) {
  317. echo $e->getErrorMessage() . PHP_EOL;
  318. }
  319. $this->success('发送成功',$code);
  320. }
  321. //校验短信验证码
  322. public function verify_sms($phone = '',$code = ''){
  323. $store_member_sms = Db::name('store_member_sms')->field('id,code')->where('phone',$phone)->where('used',0)->order('id desc')->find();
  324. if($store_member_sms['code'] == $code){
  325. return $store_member_sms['id'];
  326. }else{
  327. return 0;
  328. }
  329. }
  330. //token加密
  331. public function create_jwt($uid)
  332. {
  333. $key = md5(config('app.jwt')); //jwt的签发密钥,验证token的时候需要用到
  334. $time = time(); //签发时间
  335. $expire = $time + config('app.jwt_time'); //过期时间
  336. $token = array(
  337. "uid" => $uid,
  338. "iss" => "https://zain.com",//签发组织
  339. "aud" => "https://zain.com", //签发作者
  340. "iat" => $time,
  341. "nbf" => $time,
  342. "exp" => $expire
  343. );
  344. $jwt = JWT::encode($token, $key);
  345. return $jwt;
  346. }
  347. public function get_token(){
  348. $uid = input('uid',500);
  349. $token = $this->create_jwt($uid);
  350. $this->success('',$token);
  351. }
  352. }