diff --git a/.env.example b/.env.example index 302ea5a..0148bbd 100644 --- a/.env.example +++ b/.env.example @@ -44,4 +44,7 @@ PUSHER_APP_KEY= PUSHER_APP_SECRET= # 云片 -YUNPIAN_API_KEY= \ No newline at end of file +YUNPIAN_API_KEY= +#微信 +WEIXIN_APPID= +WEIXIN_SECRET= \ No newline at end of file diff --git a/app/Http/Controllers/Api/AuthorizationsController.php b/app/Http/Controllers/Api/AuthorizationsController.php new file mode 100644 index 0000000..774fe95 --- /dev/null +++ b/app/Http/Controllers/Api/AuthorizationsController.php @@ -0,0 +1,49 @@ +response->errorBadRequest(); + } + $driver = Socialite::driver($type); + try { + if ($code = $request->get('code')) { + $response = $driver->getAccessTokenResponse($code); + $token = array_get($response, 'access_token'); + } else { + $token = $request->get('access_token'); + if ($type == 'weixin') { + $driver->setOpenId($request->get('openid')); + } + } + $oauthUser = $driver->userFromToken($token); + + } catch (\Exception $exception) { + return $this->response->errorUnauthorized('参数错误,未获取用户信息'); + } + switch ($type) { + case 'weixin': + $unionid = $oauthUser->offsetExists('unionid') ? $oauthUser->offsetGet('unionid') : null; + + $user = $unionid ? User::where('weixin_unionid', $unionid)->first() : User::where('weixin_openid', $oauthUser->getId())->first(); + if (!$user) { + $user = User::create([ + 'name' => $oauthUser->getNickname(), + 'avatar' => $oauthUser->getAvatar(), + 'weixin_openid' => $oauthUser->getId(), + 'weixin_unionid' => $unionid, + ]); + } + break; + } + return $this->response->array(['token' => $user->id]); + } +} diff --git a/app/Http/Requests/Api/SocialAuthorizationRequest.php b/app/Http/Requests/Api/SocialAuthorizationRequest.php new file mode 100644 index 0000000..13648fb --- /dev/null +++ b/app/Http/Requests/Api/SocialAuthorizationRequest.php @@ -0,0 +1,38 @@ + 'required_without:access_token|string', + 'access_token' => 'required_without:code|string', + 'openid' => 'required_with:access_token|string' + ]; + + if ($this->get('social_type') == 'weixin' && !$this->get('code')) { + $rules['openid'] = 'required|string'; + } + + return $rules; + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 7f4eb8e..daf8852 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -29,7 +29,8 @@ class User extends Authenticatable * @var array */ protected $fillable = [ - 'name', 'phone', 'email', 'password', 'introduction', 'avatar ' + 'name', 'phone', 'email', 'password', 'introduction', 'avatar ', + 'weixin_openid', 'weixin_unionid', ]; /** diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index ea13b73..77f92e5 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; +use SocialiteProviders\Manager\SocialiteWasCalled; class EventServiceProvider extends ServiceProvider { @@ -15,6 +16,10 @@ class EventServiceProvider extends ServiceProvider 'App\Events\Event' => [ 'App\Listeners\EventListener', ], + SocialiteWasCalled::class => [ + // add your listeners (aka providers) here + 'SocialiteProviders\Weixin\WeixinExtendSocialite@handle' + ], ]; /** diff --git a/composer.json b/composer.json index 04bc445..9eb01f5 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "overtrue/laravel-lang": "^3.0", "overtrue/pinyin": "~3.0", "predis/predis": "~1.0", + "socialiteproviders/weixin": "^4.0", "spatie/laravel-permission": "~2.7", "summerblue/administrator": "~1.1", "viacreative/sudo-su": "~1.1" diff --git a/composer.lock b/composer.lock index 7b627fa..76dee20 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": "d57c94b21b3065341f86d14fbcac7859", + "content-hash": "588439ee64e05cdd8901cf40a7966df1", "packages": [ { "name": "cakephp/chronos", @@ -1659,8 +1659,70 @@ "time": "2018-03-13T18:00:18+00:00" }, { + "name": "laravel/socialite", + "version": "v3.0.12", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f", + "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0", + "illuminate/contracts": "~5.4", + "illuminate/http": "~5.4", + "illuminate/support": "~5.4", + "league/oauth1-client": "~1.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0|~5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "keywords": [ + "laravel", + "oauth" + ], + "time": "2018-06-01T15:06:47+00:00" + }, + { "name": "laravel/tinker", - "version": "v1.0.7", + "version": "v1.0.7", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", @@ -1719,7 +1781,7 @@ "laravel", "psysh" ], - "time": "2018-05-17T13:42:07+00:00" + "time": "2018-05-17T13:42:07+00:00" }, { "name": "league/flysystem", @@ -1869,6 +1931,69 @@ ], "time": "2017-06-12T11:04:56+00:00" }, + { + "name": "league/oauth1-client", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/fca5f160650cb74d23fc11aa570dd61f86dcf647", + "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0" + }, + "require-dev": { + "mockery/mockery": "^0.9", + "phpunit/phpunit": "^4.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "time": "2016-08-17T00:36:58+00:00" + }, { "name": "mews/captcha", "version": "2.2.0", @@ -2960,8 +3085,98 @@ "time": "2018-01-20T00:28:24+00:00" }, { + "name": "socialiteproviders/manager", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Manager.git", + "reference": "1de3f3d874392da6f1a4c0bf30d843e9cd903ea7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/1de3f3d874392da6f1a4c0bf30d843e9cd903ea7", + "reference": "1de3f3d874392da6f1a4c0bf30d843e9cd903ea7", + "shasum": "" + }, + "require": { + "laravel/socialite": "~3.0", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "SocialiteProviders\\Manager\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SocialiteProviders\\Manager\\": "src/", + "SocialiteProviders\\Manager\\Test\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andy Wendt", + "email": "andy@awendt.com" + } + ], + "description": "Easily add new or override built-in providers in Laravel Socialite.", + "time": "2017-11-20T08:42:57+00:00" + }, + { + "name": "socialiteproviders/weixin", + "version": "v4.0.2", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Weixin.git", + "reference": "8406e487b951650125244d2334acf4e18997d179" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Weixin/zipball/8406e487b951650125244d2334acf4e18997d179", + "reference": "8406e487b951650125244d2334acf4e18997d179", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "socialiteproviders/manager": "~2.0 || ~3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Weixin\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "xyxu", + "email": "techxu@gmail.com" + }, + { + "name": "xiami", + "email": "jhdxr@php.net" + } + ], + "description": "Weixin OAuth2 Provider for Laravel Socialite", + "time": "2017-11-18T05:09:07+00:00" + }, + { "name": "spatie/laravel-permission", - "version": "2.12.1", + "version": "2.12.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-permission.git", @@ -3021,7 +3236,7 @@ "security", "spatie" ], - "time": "2018-04-23T19:06:39+00:00" + "time": "2018-04-23T19:06:39+00:00" }, { "name": "summerblue/administrator", diff --git a/config/services.php b/config/services.php index aa4b0f8..e4d08bc 100644 --- a/config/services.php +++ b/config/services.php @@ -40,4 +40,10 @@ return [ 'secret' => env('STRIPE_SECRET'), ], + 'weixin' => [ + 'client_id' => env('WEIXIN_APPID'), + 'client_secret' => env('WEIXIN_SECRET'), + 'redirect' => env('WEIXIN_REDIRECT_URI'), + ], + ]; diff --git a/database/migrations/2018_06_03_203606_add_weixin_openid_to_users_table.php b/database/migrations/2018_06_03_203606_add_weixin_openid_to_users_table.php new file mode 100644 index 0000000..b67fe59 --- /dev/null +++ b/database/migrations/2018_06_03_203606_add_weixin_openid_to_users_table.php @@ -0,0 +1,36 @@ +string('weixin_openid')->unique()->nullable()->after('password'); + $table->string('weixin_unionid')->unique()->nullable()->after('weixin_openid'); + $table->string('password')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('weixin_openid'); + $table->dropColumn('weixin_unionid'); + $table->string('password')->nullable(false)->change(); + }); + } +} diff --git a/routes/api.php b/routes/api.php index 01b892b..aa0a65d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -29,6 +29,10 @@ $api->version('v1', ['namespace' => 'App\Http\Controllers\Api'], function ($api) $api->post('captchas', 'CaptchasController@store') ->name('api.captchas.store'); + // 第三方登录 + $api->post('socials/{social_type}/authorizations', 'AuthorizationsController@socialStore') + ->name('api.socials.authorizations.store'); + });