AuthController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. namespace App\Controllers;
  3. use App\Utils\GA;
  4. use App\Utils\Hash;
  5. use App\Utils\Tools;
  6. use Ramsey\Uuid\Uuid;
  7. use App\Services\Auth;
  8. use App\Services\Mail;
  9. use Slim\Http\Response;
  10. use voku\helper\AntiXSS;
  11. use App\Models\User;
  12. use App\Models\Setting;
  13. use App\Models\InviteCode;
  14. use App\Models\EmailVerify;
  15. class AuthController extends BaseController
  16. {
  17. public function login($request, $response, $args)
  18. {
  19. return $this->view()->display('auth/login.tpl');
  20. }
  21. public function loginHandle($request, $response, $args)
  22. {
  23. $code = $request->getParam('code');
  24. $email = strtolower(trim($request->getParam('email')));
  25. $passwd = $request->getParam('passwd');
  26. $rememberMe = $request->getParam('remember_me');
  27. $user = User::where('email', $email)->first();
  28. try {
  29. if ($user == null) {
  30. throw new \Exception('没有找到这个邮箱');
  31. }
  32. if (!Hash::checkPassword($user->pass, $passwd)) {
  33. $user->collectLoginIP($_SERVER['REMOTE_ADDR'], 1);
  34. throw new \Exception('登录密码不正确');
  35. }
  36. if ($user->ga_enable == 1) {
  37. $ga = new GA();
  38. $rcode = $ga->verifyCode($user->ga_token, $code);
  39. if (!$rcode) {
  40. throw new \Exception('两步验证码错误,如丢失密钥,请重置密码');
  41. }
  42. }
  43. $time = 3600 * 24;
  44. Auth::login($user->id, $time);
  45. $user->collectLoginIP($_SERVER['REMOTE_ADDR']);
  46. } catch (\Exception $e) {
  47. return $response->withJson([
  48. 'ret' => 0,
  49. 'msg' => $e->getMessage()
  50. ]);
  51. }
  52. return $response->withJson([
  53. 'ret' => 1,
  54. 'msg' => '登录成功,欢迎回来'
  55. ]);
  56. }
  57. public function sendVerify($request, $response, $next)
  58. {
  59. try {
  60. if (!Setting::obtain('reg_email_verify')) {
  61. throw new \Exception('不需要验证邮箱');
  62. }
  63. if (Setting::obtain('mail_driver') == 'none') {
  64. throw new \Exception('没有有效的发信配置');
  65. }
  66. $email = strtolower(trim($request->getParam('email')));
  67. if ($email == '') {
  68. throw new \Exception('请填写邮箱');
  69. }
  70. if (!Tools::emailCheck($email)) {
  71. throw new \Exception('邮箱格式不正确');
  72. }
  73. $user = User::where('email', $email)->first();
  74. if ($user != null) {
  75. throw new \Exception('此邮箱已注册');
  76. }
  77. $ipcount = EmailVerify::where('ip', $_SERVER['REMOTE_ADDR'])
  78. ->where('expire_in', '>', time())
  79. ->count();
  80. if ($ipcount >= Setting::obtain('email_verify_ip_limit')) {
  81. throw new \Exception('此IP请求次数过多');
  82. }
  83. $mailcount = EmailVerify::where('email', $email)
  84. ->where('expire_in', '>', time())
  85. ->count();
  86. if ($mailcount >= 3) {
  87. throw new \Exception('此邮箱请求次数过多');
  88. }
  89. $code = Tools::genRandomNum(6);
  90. $ev = new EmailVerify();
  91. $ev->expire_in = time() + Setting::obtain('email_verify_ttl');
  92. $ev->ip = $_SERVER['REMOTE_ADDR'];
  93. $ev->email = $email;
  94. $ev->code = $code;
  95. $ev->save();
  96. Mail::send($email, $_ENV['appName'] . ' - 验证邮件', 'auth/verify.tpl',
  97. [
  98. 'code' => $code,
  99. 'expire' => date('Y-m-d H:i:s', time() + Setting::obtain('email_verify_ttl'))
  100. ], []
  101. );
  102. } catch (\Exception $e) {
  103. return $response->withJson([
  104. 'ret' => 0,
  105. 'msg' => $e->getMessage()
  106. ]);
  107. }
  108. return $response->withJson([
  109. 'ret' => 1,
  110. 'msg' => '请查收验证码'
  111. ]);
  112. }
  113. public function register($request, $response, $next)
  114. {
  115. $anti_xss = new AntiXSS();
  116. $code = $anti_xss->xss_clean(trim($request->getParam('code')));
  117. return $this->view()
  118. ->assign('code', $code)
  119. ->assign('enable_email_verify', Setting::obtain('reg_email_verify'))
  120. ->display('auth/register.tpl');
  121. }
  122. public function registerHandle($request, $response, $args)
  123. {
  124. try {
  125. $tos = $request->getParam('tos');
  126. $name = trim($request->getParam('name'));
  127. $passwd = $request->getParam('passwd');
  128. $repasswd = $request->getParam('repasswd');
  129. $code = trim($request->getParam('code'));
  130. $emailcode = trim($request->getParam('emailcode'));
  131. $email = strtolower(trim($request->getParam('email')));
  132. $reg_mode = Setting::obtain('reg_mode');
  133. if ($tos == 'false') {
  134. throw new \Exception('请勾选同意服务条款与隐私政策');
  135. }
  136. if ($name == '') {
  137. throw new \Exception('请填写昵称');
  138. }
  139. if ($email == '') {
  140. throw new \Exception('请填写注册邮箱');
  141. }
  142. if (!Tools::emailCheck($email)) {
  143. throw new \Exception('邮箱格式不正确');
  144. }
  145. if (strlen($passwd) < 8) {
  146. throw new \Exception('密码长度不足8位');
  147. }
  148. if ($passwd != $repasswd) {
  149. throw new \Exception('两次输入的密码不相符');
  150. }
  151. if ($reg_mode == 'close') {
  152. throw new \Exception('未开放注册');
  153. }
  154. if ($reg_mode == 'invite' && $code == '') {
  155. throw new \Exception('仅开放邀请注册,请填写邀请码');
  156. }
  157. if ($reg_mode == 'invite') {
  158. $reg_invite_code = InviteCode::where('code', $code)->first();
  159. if ($reg_invite_code == null) {
  160. throw new \Exception('没有找到这个邀请码');
  161. }
  162. $invite_user = User::where('id', $reg_invite_code->user_id)->first();
  163. if ($invite_user == null) {
  164. throw new \Exception('邀请人不存在');
  165. }
  166. if ($invite_user->invite_num == 0) {
  167. throw new \Exception('邀请码可用次数不足');
  168. }
  169. }
  170. if ($_ENV['enable_reg_im']) {
  171. $imtype = $request->getParam('im_type');
  172. $imvalue = $request->getParam('im_value');
  173. if ($imtype == '0' || $imtype != '1' && $imtype != '2' && $imtype != '4' && $imtype != '5' || $imvalue == '') {
  174. throw new \Exception('选择社交软件并填写社交账户');
  175. }
  176. $imtype_exist = User::where('im_value', $imvalue)
  177. ->where('im_type', $imtype)
  178. ->first();
  179. if ($imtype_exist != null) {
  180. throw new \Exception('此社交账户已被使用');
  181. }
  182. } else {
  183. $imtype = 1;
  184. $imvalue = '';
  185. }
  186. $user = User::where('email', $email)->first();
  187. if ($user != null) {
  188. throw new \Exception('此邮箱已注册');
  189. }
  190. if (Setting::obtain('reg_email_verify')) {
  191. $mailcount = EmailVerify::where('email', $email)
  192. ->where('code', $emailcode)
  193. ->where('expire_in', '>', time())
  194. ->first();
  195. if ($mailcount == null) {
  196. throw new \Exception('邮箱验证码不正确');
  197. }
  198. }
  199. self::register_helper($name, $email, $passwd, $code, $imtype, $imvalue, 0);
  200. } catch (\Exception $e) {
  201. return $response->withJson([
  202. 'ret' => 0,
  203. 'msg' => $e->getMessage()
  204. ]);
  205. }
  206. if ($reg_mode == 'invite') {
  207. // 仅在仅允许邀请注册的情况下扣减邀请码次数
  208. $invite_user->invite_num -= 1;
  209. $invite_user->save();
  210. }
  211. return $response->withJson([
  212. 'ret' => 1,
  213. 'msg' => '注册成功'
  214. ]);
  215. }
  216. public static function register_helper($name, $email, $passwd, $code, $imtype, $imvalue, $telegram_id, $auto_login = true)
  217. {
  218. $ga = new GA();
  219. $user = new User();
  220. $antiXss = new AntiXSS();
  221. $user->money = $_ENV['reg_money'];
  222. $user->email = $email;
  223. $user->im_type = ($imtype == '') ? '1' : $imtype;
  224. $user->im_value = $antiXss->xss_clean($imvalue);
  225. $user->user_name = $antiXss->xss_clean($name);
  226. $user->port = Tools::getAvPort();
  227. $user->pass = Hash::passwordHash($passwd); // 登录密码
  228. $user->passwd = Tools::genRandomChar(16); // ss 连接密码
  229. $user->uuid = Uuid::uuid3(Uuid::NAMESPACE_DNS, $email . '|' . time());
  230. $user->t = 0;
  231. $user->u = 0;
  232. $user->d = 0;
  233. $user->transfer_enable = 0;
  234. $user->invite_num = $_ENV['reg_invite_num'];
  235. $user->auto_reset_day = 0;
  236. $user->auto_reset_bandwidth = 0;
  237. $user->sendDailyMail = 0; // 默认不发送
  238. $user->obfs = $_ENV['reg_obfs'];
  239. $user->method = $_ENV['reg_method'];
  240. $user->protocol = $_ENV['reg_protocol'];
  241. $user->obfs_param = $_ENV['reg_obfs_param'];
  242. $user->protocol_param = $_ENV['reg_protocol_param'];
  243. $user->forbidden_ip = $_ENV['reg_forbidden_ip'];
  244. $user->forbidden_port = $_ENV['reg_forbidden_port'];
  245. if ($telegram_id) {
  246. $user->telegram_id = $telegram_id;
  247. }
  248. $user->ga_enable = 0;
  249. $user->ga_token = $ga->createSecret();
  250. $user->node_connector = 0;
  251. $user->node_speedlimit = 0;
  252. $user->class = 0;
  253. $user->expire_in = date('Y-m-d H:i:s', time());
  254. $user->class_expire = date('Y-m-d H:i:s', time());
  255. $user->reg_date = date('Y-m-d H:i:s');
  256. $user->reg_ip = (empty($_SERVER['REMOTE_ADDR'])) ? '127.0.0.1' : $_SERVER['REMOTE_ADDR'];
  257. $user->theme = $_ENV['theme'];
  258. $groups = explode(',', $_ENV['random_group']);
  259. $user->node_group = $groups[array_rand($groups)];
  260. $user->save();
  261. if ($auto_login) {
  262. Auth::login($user->id, 3600);
  263. $user->collectLoginIP($_SERVER['REMOTE_ADDR']);
  264. }
  265. }
  266. public function logout($request, $response, $next)
  267. {
  268. Auth::logout();
  269. return $response->withStatus(302)->withHeader('Location', '/auth/login');
  270. }
  271. }