@artman328
2017-12-19T11:40:50.000000Z
字数 9824
阅读 982
wsc
wsc45
将 XAMPP 应用安装到某个文件夹,比如:f:\xampp
,然后修改环境变量 path , 将 f:\xampp\php
及 f:\xampp\mysql\bin
加到 path 中。
将 Laravel 框架安装到某个文件夹,或直接将提供的 Laravel 框架文件拷贝到此文件夹。如果是拷贝的,请在这个文件夹中的命令行执行:
php artisan key:generate
以重新生成应用程序的键。
在 f:\xampp\apache\conf\httpd.conf
文件的尾部,加入以下内容(此处假定你的 Laravel 项目在 f:\php_projects\86_Server_A
下):
<Directory "F:/php_projects/86_Server_A/public">
AllowOverride all
Require all granted
</Directory>
Alias /86_Server_A "F:/php_projects/86_Server_A/public/"
然后,在 F:\php_projects\86_Server_A\public\.htaccess
文件中加入 RewriteBase
一行:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# 加入下面一行
RewriteBase /86_Server_A
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
然后,重新启动 xampp 的 apache 服务器,在浏览器中输入:
http://localhost/86_Server_A
应该能够看到 laravel 应用程序的默认首页。如果不行,请认真核对以上步骤。
修改提供的 sql 脚本文件,建立相应的外键关联,加入必须的表定义。修改后内容如下:
-- phpMyAdmin SQL Dump
-- version 4.7.0
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Oct 10, 2017 at 05:46 AM
-- Server version: 10.1.26-MariaDB
-- PHP Version: 7.1.8
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
DROP DATABASE IF EXISTS baniyas_db;
CREATE DATABASE IF NOT EXISTS baniyas_db DEFAULT CHARSET utf8;
USE baniyas_db;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `worldskills_2017_serverside_default`
--
-- --------------------------------------------------------
--
-- Table structure for table `places`
--
CREATE TABLE `places` (
`id` int(11) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`latitude` float DEFAULT NULL,
`longitude` float DEFAULT NULL,
`x` int(11) DEFAULT NULL,
`y` int(11) DEFAULT NULL,
`image_path` varchar(50) DEFAULT NULL,
`description` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `schedules`
--
CREATE TABLE `schedules` (
`id` int(11) NOT NULL,
`type` enum('TRAIN','BUS') DEFAULT 'TRAIN',
`line` int(11) DEFAULT NULL,
`from_place_id` int(11) NOT NULL,
`to_place_id` int(11) NOT NULL,
`departure_time` time DEFAULT NULL,
`arrival_time` time DEFAULT NULL,
`distance` int(11) DEFAULT NULL,
`speed` int(11) DEFAULT NULL,
`status` enum('AVAILABLE','UNAVAILABLE') DEFAULT 'AVAILABLE'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `places`
--
ALTER TABLE `places`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `schedules`
--
ALTER TABLE `schedules`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `places`
--
ALTER TABLE `places`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
-- **** 以下为加入内容 *************************** -------
ALTER TABLE `schedules`
ADD foreign key(`from_place_id`) references `places`(`id`);
ALTER TABLE `schedules`
ADD foreign key(`to_place_id`) references `places`(`id`);
-- ************************************** --
--
-- AUTO_INCREMENT for table `schedules`
--
ALTER TABLE `schedules`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-- ** 增加用户表定义 ** --
CREATE TABLE users(
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(30) NOT NULL UNIQUE,
`password` varchar(100),
`role` varchar(50) NOT NULL DEFAULT 'USER'
);
-- *************************** --
-- ** 插入测试所需数据 **--
INSERT INTO users
VALUES
(1,'admin','adminpass','ADMIN'),
(2,'user1','user1pass','USER'),
(3,'user2','user2pass','USER')
;
-- ******************** --
-- ** 增加旅行路线历史记录表定义 ** --
CREATE TABLE route_histories(
id int(11) not null AUTO_INCREMENT PRIMARY KEY,
from_id int(11) NOT NULL,
to_id int(11) NOT NULL,
schedule_ids varchar(200),
count int default 0,
FOREIGN KEY(from_id) REFERENCES `places`(`id`),
FOREIGN KEY(to_id) REFERENCES `places`(`id`)
);
-- **************************** --
-- ** 增加地点搜索历史记录表定义 ** --
CREATE TABLE place_histories(
id int(11) not null AUTO_INCREMENT PRIMARY KEY,
user_id int(11) not null,
place_id int(11) not null,
count int default 0,
unique (user_id,place_id),
foreign key(user_id) references `users`(`id`),
foreign key(place_id) references `places`(`id`)
);
-- ***************************** --
-- ** 载入提供的地点数据 **--
load data local infile "d:/csv/place.csv"
into table places
fields terminated by ','
lines terminated by '\r\n'
ignore 1 lines;
-- ** 载入提供的运行时刻数据 ** --
load data local infile "d:/csv/schedule.csv"
into table schedules
fields terminated by ','
lines terminated by '\r\n'
ignore 1 lines;
--******************** --
-- ** 提交修改 ** --
COMMIT;
-- ************** --
在命令行中执行:
mysql -uroot -p
登录 mysql 客户端,执行以下命令(假定以上内容在 D:\baniyas.sql
文件中):
source d:/baniyas_db.sql
如果输出显示执行无误,可进行下一步。
编辑项目文件夹下的 routes
文件夹中的 web.php
路由文件,内容如下:
<?php
Route::get('/', function () {
return view('welcome');
});
Route::get("/api/v1/auth/unauthorized","LoginController@unauthorized");
Route::post("/api/v1/auth/login", "LoginController@login");
// API for User and Admin
Route::prefix("/api/v1/")->middleware(['check.token'])->group(function(){
//次分组加入需要用户登录才能使用的功能
Route::get("auth/logout","LoginController@logout");
});
// API for Admin
Route::prefix("/api/v1/")->middleware(['check.token','check.role'])->group(function(){
//次分组加入需要用户登录且角色为 ADMIN 才能使用的功能
});
此文件的路由组定义中,需要用到两个中间件:check.token
和 check.role
,还需要一个控制器类:LoginController
。我们在后面分别创建它们。
利用以下命令分别创建两个中间件。
CheckToken:
F:\php_projects\86_Server_A> php artisan make:middleware CheckToken
CheckRole:
F:\php_projects\86_Server_A> php artisan make:middleware CheckRole
两个文件在 F:\php_projects\86_Server_A\app\Http\Middleware
文件夹中。
CheckToken.php 内容:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckToken
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$token1 = $request->input("token"); //客户端发送的 token
$token2 = session()->get("token"); //服务器端存储的 token
//如果客户端没有传来 token
//或者传来的 token 与服务器端的 token 不符
if(!$token1 || $token1!==$token2){
//请求被重定向
return redirect("/api/v1/auth/unauthorized");
}
//把请求继续向下传递
return $next($request);
}
}
CheckRole.php 内容:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
//取出服务器端保存的用户角色名称
$role = session()->get("role");
//如果没有保存过的huo或者保存的名称不是 ADMIN
if(!$role || $role !== "ADMIN"){
//请求被重定向
return redirect("/api/v1/auth/unauthorized");
}
//把请求继续向下传递
return $next($request);
}
}
修改 F:\php_projects\86_Server_A\app\Http\Kernel.php
文件,内容如下:
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
这些中间件是所有请求都要按顺序经过的
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
* 这些中间件被归类到一个组,共同加给特定路由。web.php 中的所有路由都要经过 web 中间件分组。
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
//我们需要把下面这个中间件注释掉(不让请求经过它)
//\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
//把我们的两个中间件在此注册,才可以在路由中指定使用
'check.token' => \App\Http\Middleware\CheckToken::class,
'check.role' => \App\Http\Middleware\CheckRole::class,
];
}
在命令行执行:
F:\php_projects\86_Server_A> php artisan make:controller LoginController
得到文件 F:\php_projects\86_Server_A\app\Http\Controllers\LoginController.php
,内容如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
//
}
将三个相应处理路由的函数实现,内容如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
public function login(Request $request){
// 从请求获取用户名和密码
$username = $request->input("username");
$password = $request->input("password");
// 从数据库检索具有此用户名和密码的第一位用户(应当只有一位,first()取出了它)
$user = User::where("username",$username)->where("password",$password)->first();
// 如果用户存在
if($user){
// 将登录的用户对象信息保存在会话对象中并保存
session()->put('token',md5($username));
session()->put('role',md5($user->role));
session()->save();
// 返回数据与状态码:200
return response()->json(['token'=>md5($username),'role'=>$user->role],200);
}
// 如果没有从以上返回语句返回,说明用户不存在,返回错误信息的状态码:401
return response()->json(['message'=>"invalid login"],401);
}
public function logout(){
// 清除会话记录
session()->flush();
return response()->json(["message"=>"logout success"],200);
}
public function unauthorized(){
return response()->json(["message"=>"Unauthorized user"],401);
}
}
打开素材提供的 Testing_Server_A.postman_collection.json
文件,将其中的 <server>
用 localhost
替换,将其中的 <XX>
及 XX
用 86
替换。
打开 Postman,用 Import 菜单引入以上文件,对其中的各个请求写出相应测试,即可进行 API 测试了。