Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L03 7.x passport #48

Open
wants to merge 30 commits into
base: L03_7.x_passport
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
14257d9
2.7 API基础配置
invalid-email-address Oct 26, 2020
af5cd46
L3 3.2 安装使用easysms
invalid-email-address Oct 27, 2020
c0a2c61
L3 3.3 发送短信验证码
invalid-email-address Oct 27, 2020
6c6e864
L3 3.4 用户注册
invalid-email-address Oct 27, 2020
2972fe2
L3 3.6 速率限制
invalid-email-address Oct 27, 2020
a400317
L3 3.6 图片验证码
invalid-email-address Oct 28, 2020
210019d
L3 4.5 使用JWT
invalid-email-address Oct 28, 2020
153c909
L3 4.6 命令行生成token
invalid-email-address Oct 28, 2020
8169376
L3 5.1 获取用户信息
invalid-email-address Oct 29, 2020
b92258b
L3 5.2 编辑用户信息
invalid-email-address Oct 29, 2020
2bf537a
L3 6.1 分类列表
invalid-email-address Oct 29, 2020
f82b90d
L3 6.2 发布话题
invalid-email-address Nov 2, 2020
83808c9
L3 6.3 话题修改
invalid-email-address Nov 2, 2020
3b2cdb9
L3 6.4 删除话题
invalid-email-address Nov 2, 2020
550ef3d
L3 6.5 话题列表
invalid-email-address Nov 2, 2020
71074bc
L3 6.6 话题详情
invalid-email-address Nov 2, 2020
75d44d4
L3 7.2 删除回复
invalid-email-address Nov 3, 2020
8a994b3
L3 7.3 回复列表
invalid-email-address Nov 3, 2020
348e8cf
L3 7.4 消息通知列表
invalid-email-address Nov 3, 2020
960f60f
L3 7.5 未读消息统计
invalid-email-address Nov 3, 2020
07b8672
L3 7.6 标记通知为已读
invalid-email-address Nov 3, 2020
a29e1de
L3 8.2 用户权限列表
invalid-email-address Nov 4, 2020
2729cc4
L3 8.3 显示用户角色
invalid-email-address Nov 4, 2020
a66a529
L3 9.1 资源推荐列表
invalid-email-address Nov 4, 2020
6d1a3d5
L3 9.2 活跃用户
invalid-email-address Nov 4, 2020
8228857
L3 9.3 本地化
invalid-email-address Nov 4, 2020
036fa48
L3 10.2 话题单元测试
invalid-email-address Nov 5, 2020
af62c22
L3 11.2 安装passport
invalid-email-address Nov 6, 2020
de63028
L3 11.3 使用passport
invalid-email-address Nov 6, 2020
50bd3a8
L3 11.4 Passport第三方登录
invalid-email-address Nov 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,12 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

BAIDU_TRANSLATE_APPID=
BAIDU_TRANSLATE_KEY=

# aliyun 短信
SMS_ALIYUN_ACCESS_KEY_ID=
SMS_ALIYUN_ACCESS_KEY_SECRET=
SMS_ALIYUN_TEMPLATE_REGISTER=

# socialite weixin
WEIXIN_KEY=
WEIXIN_SECRET=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
.idea
41 changes: 41 additions & 0 deletions app/Console/Commands/GenerateToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;

class GenerateToken extends Command
{

protected $signature = 'larabbs:generate-token';
protected $description = '快速为用户生成token';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$userId = $this->ask('请输入用户ID');
$user = User::find($userId);

if(!$user){
$this->error('用户不存在');
}

$ttl = 365*24*60;
$this->info(auth('api')->setTTL($ttl)->login($user));
}
}
22 changes: 22 additions & 0 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Arr;
use Throwable;

class Handler extends ExceptionHandler
Expand Down Expand Up @@ -52,4 +53,25 @@ public function render($request, Throwable $exception)
{
return parent::render($request, $exception);
}

/*
* 重写父类方法
* 增加了code字段,以显示自定义错误码
*/
protected function convertExceptionToArray(Throwable $e)
{
return config('app.debug') ? [
'message' => $e->getMessage(),
'code' => $e->getCode(),
'exception' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => collect($e->getTrace())->map(function ($trace) {
return Arr::except($trace, ['args']);
})->all(),
] : [
'message' => $this->isHttpException($e) ? $e->getMessage() : 'Server Error',
'code' => $e->getCode(),
];
}
}
111 changes: 111 additions & 0 deletions app/Http/Controllers/Api/AuthorizationsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\AuthorizationRequest;
use Illuminate\Http\Request;
use App\Http\Requests\Api\SocialAuthorizationRequest;
use Illuminate\Support\Facades\Auth;
use Overtrue\Socialite\AccessToken;
use Illuminate\Auth\AuthenticationException;
use App\Models\User;
use Illuminate\Support\Arr;
use Tymon\JWTAuth\JWT;

use Psr\Http\Message\ServerRequestInterface;
use League\OAuth2\Server\AuthorizationServer;
use Zend\Diactoros\Response as Psr7Response;
use League\OAuth2\Server\Exception\OAuthServerException;
use App\Traits\PassportToken;

class AuthorizationsController extends Controller
{
use PassportToken;
/*
* 第三方登录
*/
public function socialStore($type,SocialAuthorizationRequest $request){
$driver = \Socialite::driver($type);
try {
if($code = $request->code){
$accessToken = $driver->getAccessToken($code);
}else{
$tokenData['access_token'] = $request->access_token;

// 微信需要增加 openid
if ($type == 'wechat') {
$tokenData['openid'] = $request->openid;
}
$accessToken = new AccessToken($tokenData);
}
$oauthUser = $driver->user($accessToken);
}catch (\Exception $e) {
throw new AuthenticationException('参数错误,未获取用户信息');
}

switch ($type){
case 'wechat':
$unionid = $oauthUser->getOriginal()['unionid'] ?? null;
if($unionid){
$user = User::where('weixin_unionid',$unionid)->first();
}else{
$user = 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;
}

$result = $this->getBearerTokenByUser($user, '1', false);

return response()->json($result)->setStatusCode(201);
}

//登录
public function store(AuthorizationRequest $originRequest, AuthorizationServer $server, ServerRequestInterface $serverRequest)
{
try {
return $server->respondToAccessTokenRequest($serverRequest, new Psr7Response)->withStatus(201);
} catch(OAuthServerException $e) {
throw new AuthenticationException($e->getMessage());
}
}

//刷新token
public function update(AuthorizationServer $server, ServerRequestInterface $serverRequest)
{
try {
return $server->respondToAccessTokenRequest($serverRequest, new Psr7Response);
} catch(OAuthServerException $e) {
throw new AuthenticationException($e->getmessage());
}
}

//删除token
public function destroy()
{
if (auth('api')->check()) {
auth('api')->user()->token()->revoke();
return response(null, 204);
} else {
throw new AuthenticationException('The token is invalid.');
}
}

//简单封装
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'Bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
]);
}
}
43 changes: 43 additions & 0 deletions app/Http/Controllers/Api/CaptchasController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\CaptchaRequest;
use Gregwar\Captcha\CaptchaBuilder;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Illuminate\Http\Request;

class CaptchasController extends Controller
{
public function store(CaptchaRequest $request,CaptchaBuilder $captchaBuilder){
$key = 'captcha-'.Str::random(15);
$phone =$request->phone;

$captcha = $captchaBuilder->build();
$expiredAt = now()->addMinutes(5);
Cache::put($key,['phone' => $phone, 'code' => $captcha->getPhrase()],$expiredAt);

$result = [
'captcha_key'=>$key,
'expired_at'=>$expiredAt->toDateTimeString(),
'url'=>url('api/v1/captchas/'.$key),
'cptach_img_content'=>$captcha->inline(),
];
return response()->json($result)->setStatusCode(201);
}

public function show(Request $request){
$key = $request->captcha_key;
$captchaData = Cache::get($key);
if(!$captchaData){
abort(403,'验证码已失效');
}

$captchaBuilder = new CaptchaBuilder($captchaData['code']);
$captchaBuilder->build();
header('Content-type: image/jpeg');

$captchaBuilder->output();
}
}
20 changes: 20 additions & 0 deletions app/Http/Controllers/Api/CategoriesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\CategoryResource;
use App\Models\Category;
use Illuminate\Http\Request;

class CategoriesController extends Controller
{
/*
* 分类列表
*/
public function show(){
CategoryResource::wrap('data');
return CategoryResource::collection(Category::all());

}
}
15 changes: 15 additions & 0 deletions app/Http/Controllers/Api/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller as BaseController;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;

class Controller extends BaseController
{
public function errorResponse($statusCode, $message=null, $code=0)
{
throw new HttpException($statusCode, $message, null, [], $code);
}
}
29 changes: 29 additions & 0 deletions app/Http/Controllers/Api/ImagesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace App\Http\Controllers\Api;

use App\Handlers\ImageUploadHandler;
use App\Http\Requests\Api\ImageRequest;
use App\Http\Resources\ImageResource;
use App\Models\Image;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class ImagesController extends Controller
{
/*
* 图片上传
*/
public function store(ImageRequest $request,Image $image,ImageUploadHandler $uploader){
$user = $request->user();
$size = $request->type == 'avatar' ? 416 : 1000;
$result = $uploader->save($request->image,Str::plural($request->type),$user->id,$size);

$image->path = $result['path'];
$image->type = $request->type;
$image->user_id = $user->id;
$image->save();

return new ImageResource($image);
}
}
19 changes: 19 additions & 0 deletions app/Http/Controllers/Api/LinksController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Resources\LinkResource;
use App\Models\Link;
use Illuminate\Http\Request;

class LinksController extends Controller
{
/*
* 资源推荐
*/
public function index(Link $link){
$links = $link->getAllCached();
LinkResource::wrap('data');
return LinkResource::collection($links);
}
}
34 changes: 34 additions & 0 deletions app/Http/Controllers/Api/NotificationsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Resources\NotificationResource;

class NotificationsController extends Controller
{
/*
* 消息列表
*/
public function index(Request $request){
$data = $request->user()->notifications()->paginate();
return NotificationResource::collection($data);
}

/*
* 未读消息数量
*/
public function stats(Request $request){
return response()->json([
'unread_count' => $request->user()->notification_count,
]);
}

/*
* 标记已读
*/
public function read(Request $request){
$request->user()->markAsRead();
return response(null, 204);
}
}
18 changes: 18 additions & 0 deletions app/Http/Controllers/Api/PermissionsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Resources\PermissionResource;
use Illuminate\Http\Request;

class PermissionsController extends Controller
{
/*
* 当前登录用户的权限列表
*/
public function index(Request $request){
$permissions = $request->user()->getAllPermissions();
PermissionResource::wrap('data');
return PermissionResource::collection($permissions);
}
}
Loading