diff --git a/app/Http/Controllers/Api/CaptchasController.php b/app/Http/Controllers/Api/CaptchasController.php new file mode 100644 index 0000000..b1d557b --- /dev/null +++ b/app/Http/Controllers/Api/CaptchasController.php @@ -0,0 +1,25 @@ +get('phone'); + $capcha = $captchaBuilder->build(); + $expiredAt = now()->addMinutes(2); + Cache::put($key, ['phone' => $phone, 'code' => $capcha->getPhrase()], $expiredAt); + $result = [ + 'captcha_key' => $key, + 'expired_at' => $expiredAt->toDateTimeString(), + 'captcha_image_content' => $capcha->inline() + ]; + return $this->response->array($result)->setStatusCode(201); + } +} diff --git a/app/Http/Controllers/Api/VerificationCodesController.php b/app/Http/Controllers/Api/VerificationCodesController.php index 2fab260..efbc313 100644 --- a/app/Http/Controllers/Api/VerificationCodesController.php +++ b/app/Http/Controllers/Api/VerificationCodesController.php @@ -9,10 +9,19 @@ class VerificationCodesController extends Controller { public function store(VerificationCodeRequest $request, EasySms $easySms) { - $phone = $request->get('phone'); + $captchaData = \Cache::get($request->get('captcha_key')); + + if (!$captchaData) { + return $this->response->error('图片验证码已失效', 422); + } + + if (!hash_equals($captchaData['code'], $request->get('captcha_code'))) { + // 验证错误就清除缓存 + \Cache::forget($request->get('captcha_key')); + return $this->response->errorUnauthorized('验证码错误'); + } + $phone = $captchaData['phone']; // 生成4位随机数,左侧补0 - - if (!app()->environment('production')) { $code = '1234'; } else { diff --git a/app/Http/Requests/Api/CaptchaRequest.php b/app/Http/Requests/Api/CaptchaRequest.php new file mode 100644 index 0000000..4e4f83e --- /dev/null +++ b/app/Http/Requests/Api/CaptchaRequest.php @@ -0,0 +1,30 @@ + 'required|regex:/^1[34578]\d{9}$/|unique:users', + ]; + } +} diff --git a/app/Http/Requests/Api/VerificationCodeRequest.php b/app/Http/Requests/Api/VerificationCodeRequest.php index fb9c00b..4cbfbcb 100644 --- a/app/Http/Requests/Api/VerificationCodeRequest.php +++ b/app/Http/Requests/Api/VerificationCodeRequest.php @@ -24,11 +24,16 @@ class VerificationCodeRequest extends FormRequest public function rules() { return [ - 'phone' => [ - 'required', - 'regex:/^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/', - 'unique:users' - ] + 'captcha_key' => 'required|string', + 'captcha_code' => 'required|string', + ]; + } + + public function attributes() + { + return [ + 'captcha_key' => '图片验证码 key', + 'captcha_code' => '图片验证码', ]; } } diff --git a/composer.json b/composer.json index 72556db..04bc445 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "dingo/api": "2.0.0-alpha2", "doctrine/dbal": "^2.6", "fideloper/proxy": "~3.3", + "gregwar/captcha": "^1.1", "guzzlehttp/guzzle": "~6.3", "hieu-le/active": "~3.5", "intervention/image": "^2.4", diff --git a/composer.lock b/composer.lock index 2c3a16c..7b627fa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6a770296ff23a10490492e56ff7e0137", + "content-hash": "d57c94b21b3065341f86d14fbcac7859", "packages": [ { "name": "cakephp/chronos", @@ -1003,8 +1003,61 @@ "time": "2017-06-15T17:19:42+00:00" }, { + "name": "gregwar/captcha", + "version": "v1.1.6", + "source": { + "type": "git", + "url": "https://github.com/Gregwar/Captcha.git", + "reference": "a96d8dffc80d6213958bd19fbdef1555e8b63ca3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Gregwar/Captcha/zipball/a96d8dffc80d6213958bd19fbdef1555e8b63ca3", + "reference": "a96d8dffc80d6213958bd19fbdef1555e8b63ca3", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "ext-mbstring": "*", + "php": ">=5.3.0", + "symfony/finder": "~3.0|~4.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "captcha", + "autoload": { + "psr-4": { + "Gregwar\\": "src/Gregwar" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Passault", + "email": "g.passault@gmail.com", + "homepage": "http://www.gregwar.com/" + }, + { + "name": "Jeremy Livingston", + "email": "jeremy.j.livingston@gmail.com" + } + ], + "description": "Captcha generator", + "homepage": "https://github.com/Gregwar/Captcha", + "keywords": [ + "bot", + "captcha", + "spam" + ], + "time": "2018-04-24T09:20:08+00:00" + }, + { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", @@ -1065,7 +1118,7 @@ "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "time": "2018-04-22T15:46:56+00:00" }, { "name": "guzzlehttp/promises", diff --git a/routes/api.php b/routes/api.php index ec34650..01b892b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -24,6 +24,11 @@ $api->version('v1', ['namespace' => 'App\Http\Controllers\Api'], function ($api) // 用户注册 $api->post('users', 'UsersController@store') ->name('api.users.store'); + + // 图片验证码 + $api->post('captchas', 'CaptchasController@store') + ->name('api.captchas.store'); + });