- _nosay
APP登陆以及OAUTH2全过程记录(一)
2017-08-30 14:27:06
我发现,在app端中使用passport时,混混沌沌,如同在梦里一般。
所以我决定 老老实实的把全过程好好的记录一下,期间资料确实少,只能自己研究,可能会走些弯路,做些没有必要的事情,君不见,当年我曾写过大约几十行代码,后来发现,有内置的方法,一行解决。但现在我也顾不了许多了,先上吧,嘲笑自己那是以后的事情啦。
由于服务端构建工作大致已经完成了,具体链接可查看
记录一下实现laravel Passport 认证的过程(服务端篇)
所以目前,我需要实现APP端的PASSPORT认证过程。
先梳理一下流程,当APP端使用短信验证码登陆的时候,服务端需要把相应的token返回给APP,APP端把token存储以后,以后在请求头带上此token,这样服务端在验证此token合法后,用户将会被认证身份,也可以赋予相应的权限。
不过我现在面临两个难点,我GOOGLE了好一会,发现在得到TOKEN的过程中,用户必须以用户名+密码的方法授权的这种组合,但是我的构想是手机号+手机验证码这个流程来完成认证,并发放TOKEN的需求。
还有就是关于官网所说的客户端凭证授权令牌这一块,我使用了官方提供的此代码,
$guzzle = new GuzzleHttp\Client; $response = $guzzle->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'client_credentials', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'scope' => 'your-scope', ], ]); echo json_decode((string) $response->getBody(), true);
发现,虽然可以获取到token,但此token好像根本不起作用,无法得到服务端的认可。搜索以后未果,没办法,还是只能回到如下方法
Route::get('/callback', function (Request $request) { $http = new GuzzleHttp\Client; $response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'authorization_code', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'redirect_uri' => 'http://example.com/callback', 'code' => $request->code, ], ]); return json_decode((string) $response->getBody(), true); });
此方法确实能得到被服务端认可的token, 但是需要传递关键参数,CODE。而此code官方并没有提到如何得到。没有办法,只能自己研究一番。
先从官方提供的VUE模板入手,我们得先看看它的client_id,client_secret,以及redirect_uri是怎么生成,怎么入库的。图片如下:
我们通过抓包发现,
其请求地址为/oauth/clients,提交的post参数如下
{"errors":[],"name":"nosay","redirect":"https://www.muzilong.cn/"}
我们追踪到相应的控制器中,找到了对应的入库代码
public function store(Request $request) { $this->validation->make($request->all(), [ 'name' => 'required|max:255', 'redirect' => 'required|url', ])->validate(); return $this->clients->create( $request->user('admin')->getKey(), $request->name, $request->redirect )->makeVisible('secret'); }
当然,因为我是后台授予认证,所以把$request->user()->getKey()改为$request->user('admin')->getKey();了, 这个在前文中有提到。
看了一下,无非就是一个数据库插入的操作,其中secret为一个随机生成的40位字符串。
这样的话,我们在APP中的第一步,可以判断此用户是否已经生成了相应的记录,期间我注意到,相应的表oauth_clients中,存在一个revoked字段,当从前台删除的时候,此字段的值就直接变成1,其实并不是传统意义上的删除,是一个伪删除。
所以我们要判断此用户是否已经存在记录,并且revoked字段为0。如果查询不到的话,我们插入相应的数据,如果查询到了的话,直接使用此secret即可。
创建一个repository,主要获取秘钥(secret),授权码(code),令牌(access_token),等等。
先上一个获取secret的相关方法,
public function getMyOauthSecretById($id) { $clientRepository = new ClientRepository(); $clentInfo = $clientRepository->getActiveByUser($id); $data = []; if(is_object($clentInfo)) { $data['secret'] = $clentInfo->secret; $data['id'] = $clentInfo->id; }else{ $clentInfo = $clientRepository->create( $id, "nosay", "https://www.muzilong.cn/" )->makeVisible('secret'); $data['secret'] = $clentInfo->secret; $data['id'] = $clentInfo->id; } return $data; }
接下来我们需要得到授权码