转载

小白的边学边写,一个基于laravel的APP接口【API】(二)

前言

根据上一篇文章,我们已经吧 dingo/api 给安装并且调试好了,那么下一步,就是来完善咱们的API了。

最首要的步骤一定是要先把注册的功能给完善了,好了,那就给第一条正式API起个名字吧——

http://localhost/register

首先先对这条API进行分析。这是一个用户注册的API,新用户通过访问它来注册账号,之后才能有权限进行其他的操作,享受其它的APP服务。那么我们在访问的时候,就应当把正确的信息输入进去,因为客户端是APP,所以要输入的字段应该是这些——(手机号)phone、(密码)password。

那么在一切准备就绪以后,当服务器处理完操作以后,我们又该获得什么callback呢?

接下来就是我自己作为一个新手小白的个人理解了。当注册成功以后,我们应该立即返回确认用户登录的token值,并且作为APP的config变量给储存起来,直到退出时删除,或者超出时间后删除。

分析完毕,开始实践

在开始之前呢,我们要在项目里安装 JWT(JSON WEB TOKEN) ,这是一种API的验证方式,详细的部分可以去看文档,它的主要作用就是在客户端的用户发出注册和登录的请求之后,返回一串token值,在之后成功登录以后以这个token值作为凭证来验证是否有获取资源的权限。

如何安装请看这个 JWT

确定安装好 JWT 以后,首先就来创建路由吧。

首先打开routes.php,修改路由

Route::post('/register', 'Auth/AuthenticateController@register');

然后创建一个控制器,在laravel项目下运行

php artisan make:controller Auth/AuthenticateController

接下来,我们直接用纯html页面当做APP,去测试API,创建新的test文件夹,结构如下

test/ ├── css/ │   └── bootstrap.min.css ├── js/ │   ├── jquery.min.js │   └── bootstrap.min.js ├── fonts/ │   ├── glyphicons-halflings-regular.eot │   ├── glyphicons-halflings-regular.svg │   ├── glyphicons-halflings-regular.ttf │   ├── glyphicons-halflings-regular.woff │   └── glyphicons-halflings-regular.woff2 └── register.html

在register.html文件里添加内容

<!DOCTYPE html> <html lang="zh-CN">     <head>       <meta charset="utf-8">       <meta http-equiv="X-UA-Compatible" content="IE=edge">       <meta name="viewport" content="width=device-width, initial-scale=1">       <title>注册</title>       <link href="css/bootstrap.min.css" rel="stylesheet">     </head>     <body>         <nav class="navbar navbar-default">             <div class="container">                 <div class="navbar-header">                     <!-- Collapsed Hamburger -->                     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#spark-navbar-collapse">                         <span class="sr-only">切换导航</span>                         <span class="icon-bar"></span>                         <span class="icon-bar"></span>                         <span class="icon-bar"></span>                     </button>                     <!-- Branding Image -->                     <a class="navbar-brand" href="#">                         <b>i ·</b> APP                     </a>                 </div>                 <div class="collapse navbar-collapse" id="spark-navbar-collapse">                     <!-- Left Side Of Navbar -->                     <ul class="nav navbar-nav">                         <li><a href="#">登录</a></li>                     </ul>                     <!-- Right Side Of Navbar -->                     <ul class="nav navbar-nav navbar-right">                         <!-- Authentication Links -->                     </ul>                 </div>             </div>         </nav>         <div class="container">             <div class="row">                 <div class="col-md-8 col-md-offset-2">                     <div class="panel panel-default">                         <div class="panel-heading">注册</div>                         <div class="panel-body">                             <form  id="register" class="form-horizontal">                                  <div class="form-group">                                     <label class="col-md-4 control-label">用户名</label>                                     <div class="col-md-6">                                         <input type="text" class="form-control" name="name">                                     </div>                                 </div>                                  <div class="form-group">                                     <label class="col-md-4 control-label">手机号</label>                                     <div class="col-md-6">                                         <input type="text" class="form-control" name="phone">                                     </div>                                 </div>                                  <div class="form-group">                                     <label class="col-md-4 control-label">密码</label>                                     <div class="col-md-6">                                         <input type="password" class="form-control" name="password">                                     </div>                                 </div>                                  <!-- <div class="form-group">                                     <label class="col-md-4 control-label">密码确认</label>                                     <div class="col-md-6">                                         <input type="password" class="form-control" name="password_confirmation">                                     </div>                                 </div> -->                                  <div class="form-group">                                     <div class="col-md-6 col-md-offset-4">                                         <button type="submit" class="btn btn-primary">                                             <i class="fa fa-btn fa-user"></i>立即注册                                         </button>                                     </div>                                 </div>                             </form>                         </div>                     </div>                 </div>             </div>         </div>         <script src="js/jquery.min.js"></script>         <script src="js/bootstrap.min.js"></script>         <script type="text/javascript">             var $registerForm = $('#register');             var response;                    $registerForm.submit(function(){                 $.ajax({                     type: "post",                     url: "http://localhost/register",                     data: $(this).serialize(),                     async: false,                     dataType:'json',                     success: function(data){                         alert(JSON.stringify(data));                      },                     // complete: function(){                     //     alert('ok');                     // },                     // error: function(XMLHttpRequest, textStatus, errorThrown) {                     //     alert(XMLHttpRequest.status);                     //     alert(XMLHttpRequest.readyState);                     //     alert(textStatus);                     // }                 });             });         </script>   </body> </html> 

AuthenticateController 里添加如下函数

<?php  namespace App/Http/Controllers/Auth;  use Illuminate/Http/Request;  use App/Http/Requests; use App/Http/Controllers/Controller;  use JWTAuth; use Tymon/JWTAuth/Exceptions/JWTException; use App/User; class AuthenticateController extends Controller {     public function authenticate(Request $request)     {         // grab credentials from the request         $credentials = $request->only('email', 'password');          try {             // attempt to verify the credentials and create a token for the user             if (! $token = JWTAuth::attempt($credentials)) {                 return response()->json(['error' => 'invalid_credentials'], 401);             }         } catch (JWTException $e) {             // something went wrong whilst attempting to encode the token             return response()->json(['error' => 'could_not_create_token'], 500);         }          // all good so return the token         return response()->json(compact('token'));     }      public function register(Request $request) {          $newUser = [              'name' => $request->get('name'),             'phone' => $request->get('phone'),             'password' => bcrypt($request->get('password')),         ];         $user = User::create($newUser);         $token = JWTAuth::fromUser($user);          return response()->json(compact('token'));     } } 

例子很简单,就是储存请求的数据然后返回 token 值。

这里就不得不来说说我遇到的一个大坑

其实按照以上的代码完全可以将新用户写入数据库的。但是!

token 值不能被返回!这就让人很头大了。于是我又看了看文章,发现以上的那些操作叫做跨域请求。在laravel文档里也有提及,对,就是那个叫 jsonp 的东东。于是又看了些文章,把ajax方法修改成了这个样子

$.ajax({     type: "get",     url: "http://localhost/register",     data: $(this).serialize(),     async: false,     dataType:'jsonp',     jsonp: 'callback'     success: function(data){         alert(JSON.stringify(data));      },     complete: function(){         alert('ok');     },     error: function(XMLHttpRequest, textStatus, errorThrown) {         alert(XMLHttpRequest.status);         alert(XMLHttpRequest.readyState);         alert(textStatus);     } });

这下又可以写进去了,但是呢!还是没有 token 值的出现。。。

而且呢,请求方式也被换成了get,这是为什么呢?后来才知道这是因为 jsonppost 根本不可能实现,或者说实现起来太难,所以我也就不为难自己了。我到那时就完全的跑偏了。。。又把 ajax 的方法改了回去,打开控制台,再试一遍,才发现,原来想要实现跨域,要在请求的 header 中加入 Access-Control-Allow-Origin 属性。

这下子感觉有希望了,于是立即创建一个 http 中间件吧。

php artisan make:middleware AccessMiddleware

在里面写上

<?php  namespace App/Http/Middleware;  use Closure;  class AccessMiddleware {     public function handle($request, Closure $next)     {            header('Access-Control-Allow-Origin: *');         header('Access-Control-Allow-Methods: GET, POST, OPTIONS');         header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With');         header('Access-Control-Allow-Credentials: true');         return $next($request);     } }

记得在kernel.php文件中注册中间件哟,在 $routeMiddleware 里添加

'access' => /App/Http/Middleware/AccessMiddleware::class, 

接下来再来修改路由

Route::group(['middleware' => 'access'], function () {     Route::post('/register','Auth/AuthenticateController@register'); });

然后再来测试一下,输入表单,点立即注册,之后 bingo ,token值出来了。

用户信息也被正常写入,之后就可以欢快的扩展注册机制啦。

在这里先规划一下吧。首先在控制器内添加表单验证,然后返回不同的 json 数据给客户端。但是毕竟我不是专业的,我只是爱好这个才去写这些东西的,关于应该返回什么数据现在脑子里还是一片混乱。 如果有大神偶然间看到了我的这篇文章,希望可以给我一点指导和建议,十分的感谢!

最后

上面的例子完全是我自己看文档+原创给整出来的,如果有错请及时告诉我哟~

上面的例子到最后虽然都实现了,但是我仍然觉得很 low,毕竟个人的智慧还是有限的。如果大家有对这个十分感兴趣,可以联系我,咱们可以一起边学边做,共同进步!我的邮箱: lwx12525@qq.com

如果恰巧大神路过,请务必给我一些指导,小白将万分的感谢 O(∩_∩)O~~

原文  https://segmentfault.com/a/1190000004614022
正文到此结束
Loading...