Login.php 15 KB

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