小白的邊學邊寫,一個基於laravel的APP接口【API】(二)

前言

根據上一篇文章,咱們已經吧dingo/api給安裝而且調試好了,那麼下一步,就是來完善我們的API了。
最首要的步驟必定是要先把註冊的功能給完善了,好了,那就給第一條正式API起個名字吧——javascript

http://localhost/register

首先先對這條API進行分析。這是一個用戶註冊的API,新用戶經過訪問它來註冊帳號,以後纔能有權限進行其餘的操做,享受其它的APP服務。那麼咱們在訪問的時候,就應當把正確的信息輸入進去,由於客戶端是APP,因此要輸入的字段應該是這些——(手機號)phone、(密碼)password。
那麼在一切準備就緒之後,當服務器處理完操做之後,咱們又該得到什麼callback呢?
接下來就是我本身做爲一個新手小白的我的理解了。當註冊成功之後,咱們應該當即返回確認用戶登陸的token值,而且做爲APP的config變量給儲存起來,直到退出時刪除,或者超出時間後刪除。php

分析完畢,開始實踐

在開始以前呢,咱們要在項目裏安裝JWT(JSON WEB TOKEN),這是一種API的驗證方式,詳細的部分能夠去看文檔,它的主要做用就是在客戶端的用戶發出註冊和登陸的請求以後,返回一串token值,在以後成功登陸之後以這個token值做爲憑證來驗證是否有獲取資源的權限。css

如何安裝請看這個JWThtml

肯定安裝好JWT之後,首先就來建立路由吧。
首先打開routes.php,修改路由java

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

而後建立一個控制器,在laravel項目下運行jquery

php artisan make:controller Auth/AuthenticateController

接下來,
咱們直接用純html頁面當作APP,去測試API,建立新的test文件夾,結構以下laravel

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文件裏添加內容git

<!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裏添加以下函數github

<?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值。ajax

這裏就不得不來講說我遇到的一個大坑

其實按照以上的代碼徹底能夠將新用戶寫入數據庫的。可是!
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~~

相關文章
相關標籤/搜索