API的小结===一定要看

4月7日:

1、composer干什么的?

composer 是 php的 依赖管理工具。



依赖:
	A类 -> B类
在没有composer之前:
	include  a.class.php
	include b.class.php

	$obj = new A();

有了composer之后,composer会自动把需要的类加载进来。

	$obj = new A();

2、Linux安装Composer:

1、下载php-composer,执行下列命令其中一个即可,下载成功之后会在目录下产生一个composer.phar的文件

(1)curl -sS https://getcomposer.org/installer | php


(2)php -r "readfile('https://getcomposer.org/installer');" | php


2、把composer移动到 /usr/sbin

	mv composer.phar  /usr/sbin/composer

	添加权限:
	chmod +x  /usr/sbin/composer

3、输入composer 出现提示页面说明安装成功

	composer -v

3、composer切换镜像源:

1、打开链接

	https://developer.aliyun.com/composer

2、切换镜像源为阿里云

	composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

3、下载Laravel框架。

创建API的项目:
composer create-project --prefer-dist laravel/laravel api -vvv

创建H5的项目:
composer create-project --prefer-dist laravel/laravel h5 -vvv

4、可能会遇到的错误:

红色提示: proc_open 错误:  【 因为安全原因,proc_open函数被禁用了 】

解决:
	(1)通过 find 找到php.ini

		find / -name php.ini

	(2) php的配置文件的目录在
		/usr/local/php/etc/php.ini

	(3) 打开php的配置文件
		vim /usr/local/php/etc/php.ini

	(4) 在vim的普通模式下  输入 
		/disable_functions 
	(5)点击回车搜索,在这一行前边加上 ; 
		保存退出 :wq

	(6)重启php-fpm
		killall phpf-fpm
		/usr/local/php/sbin/php-fpm

Connection time out :

	连接超时,把当前目录删除了,重新执行composer进行下载

5、php关于 disable_functions
指的是php的禁用函数。
system: 执行一些系统的命令

6、LNMP:

L: Linux 
N: Nginx
M: MYSQL
P: php

LAMP:
L: Linux
A: Apache
M: MYSQL
P: php

7、Linux使用Nginx如何配置域名:

Nginx的安装路径:
	/usr/local/nginx
Php的安装路径:
	/usr/local/php
Mysql:
	/usr/local/mysql

配置Nginx域名的过程: 【外网域名】

	1、先把域名解析到阿里云的服务器上

	2、在本地的命令行窗口 ping 一下 刚配置的域名

	3、找到nginx的配置文件

		/usr/local/nginx/conf/nginx.conf

	4、在Nginx配置文件的最后添加,在{}中添加
		include conf.d/*.conf;

		【加载当前目录下的conf.d下的 以conf结尾的文件】
	
	5、在/usr/local/nginx/conf/创建一个conf.d的目录
		mkdir conf.d

	6、在/usr/local/nginx/conf/conf.d目录下创建文件
		vim  1908api.phpclub.top.conf

		把一个完整的server 复制进去


	7、修改server name 和 root 
		root  访问的目录,指定到laravel框架的public
		server_name  配置成我们的域名

	8、重启下我们的Nginx
		/usr/local/nginx/sbin/nginx -t 【检查一下nginx配置是否正确】
		/usr/local/nginx/sbin/nginx -s reload

	9、访问一下我们的域名 出现laravel框架欢迎页面说明ok

8、阿里云域名解析:

记录类型:A  讲域名解析到ipv4的地址
		CNAME  讲一个域名指向另外一个域名

9、服务器提示500错误,没有显示出来具体的错误信息,如何解决?

问题主要原因:
	服务器没有开启php相关的报错。

如何解决: [在php.ini中需要修改配置]

	1、 vim /usr/local/php/etc/php.ini

	2、搜索 display_errors  【 是否显示php相关的错误 】

		把配置项从 off 修改为 on

	3、重启php-fpm
		killall php-fpm
		/usr/local/php/bin/php-fpm

laravel框架可能是 app_debug 没有开启,
	(1)在laravel框架下找到 app_debug选项  把false 改成true

	(2)   'env' => env('APP_ENV', 'dev'),

		    'debug' => (bool) env('APP_DEBUG', true ),

Linux命令:

# 查找文件的命令
find 目录 -name php.ini

# vim 搜索关键字
在普通模式下:
	输入 /要搜索的内容

重启php-fpm
	killall phpf-fpm
	/usr/local/php/sbin/php-fpm

杀死进程:
	killall 进程名字

查看进程使用

	ps -ef | grep nginx

修改权限
	chmod 

修改用户组:
	chgrp

修改所有者:
	chown

查看端口使用情况
	netstat -ntlpu

查看服务器的内存:
	free 
	free -m 按照mb查看
	free -g  按照gb查看

查看占用系统资源比较多的进程:
	top命令

Linux下的文件都是归属用户的,而用户呢,归属于用户组。

这样的话话就意味着文件属于某个用户和某个用户组。

ll的时候可以看到文件的用户和用户组
d rwx r-x r-x 2 root root 4096 7月 18 2019 openssl

  • rw- r-- r-- 1 root root 1802240 3月 23 2019 php-7.3.3.tar.gz

d 代表的是目录 (dir)

  • 代表的是是一个文件 (file)

第一个root代表的是 所有者
第二个root代表的是 所属组

后边9个字母代表的是具体的权限:

rwx read write exec
4 2 1

其中三个三个一组:

前三个 rwx 自己的权限 【所有者、所属者】 u = user
中间三个 rwx 组内用户的权限 【所在组、所有组】 g = group
后三个 rwx 其他用户的权限 o = other

chmod 777 代表的是:

7代表的是 4 + 2 + 1
第一个7代表的是 自己的权限
第二个7代表的是 组内用户的权限
第三个7代表的是 其他用户的权限

chmod +x 给所有人都加上执行的权限

给组内用户加权限:
chmod g+x 文件名

4月8号:
apk: android application package
ipk: Ios application package

API基本认知:【应用程序接口】
application programing interface

php是运行在服务端的脚本语言。

客户端软件:
需要把安装包下载下来,安装在终端设备上。

为什么要写API接口?

因为客户端的程序,运行在客户端,如果要操作数据库,需要把数据库相关信息硬编码到程序中

而客户端的程序可能会被反编码【把代码解析回来】,数据库相关信息都会暴露出来,不安全、

所以客户端不允许直接访问mysql


为了解决这个问题,所以就产生了API接口。因为一般API都是运行在服务端的,服务端的脚本语言相对比较安全

客户端的程序通过 访问接口去访问数据库。

API可以用什么语言进行开发:
php、java、python、.net【asp】 、 nodejs、 go等等

使用接口开发的好处:
1、可以做到统一的修改,如果统一使用接口,可以直接修改接口,所有的地方都会跟着修改。
2、方便系统去创建一些安全策略、
3、接口可以实现统一的管理,数据都从接口出去。
4、移动互联网成为主流,客户端的程序,必须要使用到接口。

如何去写一个接口?

做接口之前的准备工作:

1、接口文档

	(1)告诉别人如何调用你的接口
			get post   
			是否需要加密、签名等等

	(2)接口的用途
				
	(3)接口的地址  http://api.com/user/login

	(4)接口的请求方式  get post请求

	(5)输入的参数

	(6)返回的数据

	(7)输入参数的一个实例

	(8)能给出调用接口的实例代码

接口返回的数据: xml json

接口返回的数据,统一为JSON格式。

如何调用接口:
file_get_contents [用的比较多]
curl [用的比较多]
fopen
fsockopen
socket

给接口传递数据:

1、接口中的所有参数,必传参数必须传递

2、根据接口的请求方式,使用对应http请求方式吧数据传递到服务端

3、如果接口需要数据,需要吧数据拼接成数组格式,把所有的数据节点放入data中,把整个数据传递到API段,
   API接受数据的时候,会直接取传递到数据下的 data节点

	demo:
		$arr = [
			'user_name' => 'zhangsan',
			'password' => '123456'
		];

		$api_request_arr['data'] = $arr;

同源策略:

A网站去请求B网站的接口。

为什么要有同源策略?
	为了保证网站的安全,浏览器会限制我们的网站,发起请求只能请求本域名下的接口。

同源策略的要求:
	(1)同域名
	  【
		http://1908h5.phpclub.top/login
		http://1908api.phpclub.top/login
		】
	(2)同端口 
		【http://1908h5.phpclub.top:80 http://1908h5.phpclub.top:81】
	(3)同协议 ( http和https协议 )
		http://1908h5.phpclub.top/login
		https://1908h5.phpclub.top/login

跨域问题:
	http://1908h5.phpclub.top/login它请求了另外一个域名【http://1908api.phpclub.top/login】下的接口。

主域名:
	phpclub.top

一级域名:[ 域名前边是www这个是一级域名 ]
	www.phpclub.top	

除了一级域名之外,其他的域名统一被称为子域名。
二级域名:
	1908h5.phpclub.top 【二级域名】
	1908api.phpclub.top
三级域名:
	android.api.phpclub.top

http://1908h5.phpclub.top/login
http://1908api.phpclub.top/login

用户表中的随机码:

用户表中的盐值字段,是用来防止相同的密码在数据库中存储的结果是一样的。

给每个用户都生成一个随机码(盐值),在存储用户的密码的时候,需要把 密码和随机码都存起来。

密码存到数据库的时候,把密码和随机码 一块md5 生成的结果存入数据库中。

如何解决跨域问题?

1、JSONP

	放服务端返回一段js代码,通过执行js代码,回调对应的方法中。

	JSONP格式只支持GET请求,是没有办法发送POST请求的。

	通过回调函数的方式解决跨域问题。

	(1) 把ajax请求返回的数据格式修改为 JSONP格式 

	(2) 在ajax中添加 jsonpCallback:logincallback参数,

	(3) 在页面中添加一个 function logincallback(){} 

	(4) ajax会发送一个get请求,并且希望是返回值是jsonp格式

	(5) 服务端接受 callback参数,把返回的数据 放到 logincallback( JSON数据 ) 。

	(6) 客户端就能获取到跨域名下的json数据了


2、让服务端可以指定 特定的域名可以请求

	// 允许http://1908h5.phpclub.top发起的跨域请求  
	header("Access-Control-Allow-Origin:http://1908h5.phpclub.top"); 
	//如果需要设置允许所有域名发起的跨域请求,可以使用通配符 *  
	header("Access-Control-Allow-Origin:*");
	header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With'); 

前段通过js调用后端接口的时候,会提示跨域的错误,如何解决:

	1、Jsonp
	2、设置header

问: 后端调用接口会提示跨域的问题么?

	CURL调用接口,是不会提示错误的。
	后端调用接口是不会出现跨域问题的。

4月9号:

写一个登录接口

1、h5调用接口, 需要 传递用户名和密码

2、服务端【API】接受用户名和密码

3、去数据库判断是否正确

4、根据查询结果给出对应的提示信息即可。

登陆接口的业务逻辑:

(1) 接受用户名,判断用户名非空
(2) 接受密码,判断密码非空
(3) 根据用户名取出用户信息,如果没有去到说明用户不存在
(4) 取到之后,判断密码是否一致,不一致提示错误,如果一致的话 说明登陆成功。

需要考虑的问题?

之前的登陆是如何实现的?(如何识别用户是否登陆)

	如果用户登陆成功,把用户的信息写入session(存在服务端的文件中),如果session中有值,说明是登陆状态,如果session中没有值,说明现在是没有登陆的状态。
	【session是基于cookie的,sessionid是存在客户端的浏览器上】

使用接口如何记录登陆状态?		

	因为接口是提供的数据服务,是不用基于浏览器的。所有我们之前是把登陆记录在了session中,但是在接口开发中,把登陆信息存入session是没有办法使用的。

	接口要实现记录登陆状态,要使用到令牌(token)去记录登陆状态。

如何在接口使用令牌记录记录用户的登陆状态?

给登陆成功的用户下发一个令牌,下一次访问接口的时候,都需要通过带着令牌过来才能正常的访问接口。

需要把令牌存在哪里?
(1)存MYSQL
(2)存redis、memcache
(3)存文件

POSTMAN:
接口测试工具。

1、创建一个集合【左上角的+new】,选择Collection

2、把鼠标放在集合上边,会出现三个点,点击一下

3、选择 Add Request

4、添写Request name 点击save

5、在后边主体的栏目中

6、选择请求方式为POST方式

7、在文本框添加请求的路径 http://1908api.phpclub.top/user/login

8、在文本框下边点击body ,在body选择 x-www-form-urlencode

9、添加参数,填写对应的值
data[user_name]
data[password]

10、点击send 发送请求。

登陆接口 /user/login

1、登陆接口中,需要接受参数 【 加密解密、验证签名等 】

2、因为所有的接口都需要做加密 解密 、签名等,为了方便,我们把这块放到了中间件去处理

3、链接服务器,创建中间件

4、到api的目录之下命令 php artisan make:middleware ApiCheck

5、注册中间件

找到kernel.php

################## 第一种:添加 路由中间件 ##################
6、在kernel.php添加路由中间件

$routeMiddleware 添加

	 'apicheck' =>  \App\Http\Middleware\ApiCheck::class,

7、在web.php中在对应的路由后边添加

Route::any('/user/login', 'UserController@login')->middleware('apicheck');

################## 第一种:添加 中间件组 ##################
6、在kernel.php添加路由中间件
$middlewareGroups 添加

	'myapi' => [
        \App\Http\Middleware\ApiCheck::class,
    ]

7、 在web.php中修改中间件组

Route::group(['namespace' => 'Api','middleware' =>['myapi']], function(){

    Route::any('/user/login', 'UserController@login');

    Route::any('/login2', 'UserController@login2');
});

######################################################
8、在中间件添加:

# 接受客户端传过来的data数据
$data = $request -> post('data');

# 把接收的数据做一个替换
$request -> replace( $data );

return $next($request);

9、接受参数,并且判断参数不能为空

10、创建一个usermodel php artisan make:model UserModel

11、创建错误提示信息类

在app目录创建 ParamMsg的目录

在目录下创建一个Error.php的类

在类中定义常量

12 、定义 error success showapierror

######### 4月13日 周考题 ################

命名空间:

主要是为了解决类名冲突的问题。

MYSQL常用的聚合函数:
AVG
sum
count
max
min

redis清空所有key使用: flushall

常用的端口号:
http:80
https:443
redis:6379
memcache:11211
nginx : 80
mysql:3306
php-fpm:9000

php-fpm:
php的进程管理器

CGI:
通用网关接口
common gateway interface 通用网关接口

webserver:
nginx 和 apache

在Web发展的最初,全球的互联网的网页是静态的【 大家看到的页面是一样的 】
【所有人得到的网页都是相同的】

为了解决大家看到的页面都是一样的,实现动态页面,所以产生了CGI

在没有CGI之前
1、 用户请求web服务器
2、 web服务器接收到这个请求
3、 直接返回一个静态的页面 【所有的用户看到的是一样的】

希望可以看到不同的页面,如何解决?
产生了CGI

有了CGI之后:
1、 用户请求web服务器
2、 web服务器判断是否是一个动态的请求
3、 如果是动态请求,web服务器自己是没有办法处理的,所以他把这个请求交给了CGI
4、 CGI可以和后段数据库进行交互,这样的话就可以实现动态的网页。

CGI规定了 web服务器和后段程序如何进行交互。

CGI:用来处理一些动态的请求。

CGI存在的问题:
每次接收到请求,都需要初始化一个进程去处理。效率比较低。

FastCgi:
fastcgi是用来提高cgi的效率的。

fastcgi启动的时候,会启动1个主进程和多个子进程。

			Nginx
			  |	
			  |
		   1个主进程【fastcgi。php-fpm】


	子进程1  子进程2  子进程3

502的错误: 【网关错误】
Nginx没有找到php-fpm。

504的错误: 【网关超时】
后段php-fpm处理不了那么多请求,nginx吧请求交给php-fpm处理不过来,
会处于等待的状态,超过指定时间之后,nginx会自动断开链接,就会提示504

php-fpm: php的进程管理器【php的fastcgi】

php-fpm:
默认监听的端口是9000

php-fpm运行的2种模式: 具体的配置参考【etc/php-fpm.conf】

运行模式:
	[www]
	;listen = 127.0.0.1:9000
	;listen = 0.0.0.0:9000
	listen=/dev/shm/php-cgi.sock


1、socket unix:/dev/shm/php-cgi.sock
2、端口号 9000

nginx和php-fpm交互是通过:fastcgi_pass

判断是否是php请求

location ~ [^/].php(/|$) {
# 如果是php的请求交给 9000端口
#fastcgi_pass remote_php_ip:9000;

# 把请求交给一个socket文件
fastcgi_pass unix:/dev/shm/php-cgi.sock;

# 默认访问index
fastcgi_index index.php;

# 包含fastcgi.conf文件
include fastcgi.conf;

}

需要记住的:

php-fpm两种模式:

端口号
socket文件

nginx和php-fpm交互:

location ~ [^/].php(/|$) {
# 如果是php的请求交给 9000端口
#fastcgi_pass remote_php_ip:9000;

# 把请求交给一个socket文件
fastcgi_pass unix:/dev/shm/php-cgi.sock;

# 默认访问index
fastcgi_index index.php;

# 包含fastcgi.conf文件
include fastcgi.conf;

}

CGI:
通用网关接口

502: 网关错误,nginx没有找到php-fpm
504: 网关超时,php-fpm处理不过来了。

Linux vim:

删除一行使用 dd
删除多行使用 行数 dd

MYSQL 事务的四大特性:
原子性:多个sql语句一块执行,当作一个原子的操作,要么全部成功,要么全部失败。
持久性:事务执行成功之后对数据库造成的影响是持久的,不可逆的。
隔离型:多个事务相互隔离,互不影响。
一致性:数据库执行事务之后,一致性不会被破坏。

redis数据类型:
字符串 string
列表。 list
集合。set
有序集合。zset
哈希 hash

############ 登陆令牌 #############
CREATE TABLE exam_user_token (
id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增id’,
user_id int(11) DEFAULT NULL COMMENT ‘用户的id’,
token varchar(64) DEFAULT NULL COMMENT ‘用户的访问令牌’,
expire int(11) DEFAULT NULL COMMENT ‘令牌的过期时间’,
login_type tinyint(4) DEFAULT NULL COMMENT ‘登陆的终端’,
status int(11) DEFAULT NULL COMMENT ‘状态’,
ctime int(11) DEFAULT NULL COMMENT ‘创建时间’,
utime int(11) DEFAULT NULL COMMENT ‘修改时间’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

一天的秒数

60*60 = 3600 * 24

############################################
因为部分接口必须登陆才能访问,所以就要用到令牌。
############################################

uniqid 是php生成不重复的字符串。

1、生成的令牌有效期是一天,一天之内这个令牌都可以使用

2、如果超过一天,如果在这一天之内有过访问,会自动延长token的有效期

3、token的有效期会自动延长,按照最后一次访问之后,24小时失效。

4、登陆的时候需要重新生成新的令牌,因为我们要保证,一个用户同时只能在一个终端登陆一次。

用户如果频繁登陆怎么办? 【每次都给数据库写入一条数据,数据库不就炸了】

限制时间,一分钟不能连续登录五次。

instanceof 是用判断变量是否是这个类生成对象

语法 对象的名字 instanceof 类名

$user_obj instanceof UserModel

############# http协议:
文本:txt、doc、 一般情况下文本里都是文字。
超文本: 不仅仅可以是文字,也可以有图片、视频等。

超文本传输协议: 【 HyperText Transfer Protocol 】
可以在互联网上传递文字、图片、视频等

http基于客户端和服务端的。

http请求的流程:

1、客户端主动发送请求的到服务端

	请求分为:
		请求行。【请求的路径】
		请求头。【header】
		空行	【区分请求的头部和主体】
		请求的数据 【body】

		http://localhost
		header:content-type

		data[user_name]=zhangsan&data[password]=123456

2、服务端接受到请求,处理


3、服务端把相关的数据返回回去,给客户端

	状态行
	响应头部
	空白行
	响应的数据

	DEMO:
	200 ok
	header信息

	返回的内容

http请求需要注意的:

请求必须是客户端主动发起,服务端是接受客户端的请求,把对应的资源返回给客户端。
服务端是不能主动给客户端发消息。

为了保证http连接的可靠性,每次http请求都需要三次tcp握手

传输层协议: 【 不同主机之间怎么传递数据 】
tcp和udp

tcp: 面向连接的,数据传输的可靠性比较高,适合传输大量的数据,速度慢。【打电话】
udp: 不需要建立连接,直接发送数据,速度高于tcp传输,但是安全性低于tcp,适合传输少量的数据【发短信】

tcp三次握手: 【 客户端和服务端 】

主要是为了保证建立一个可靠的连接

1、客户端给服务端发送一个tcp的请求
2、服务端接受到消息,给客户端发送一个tcp的请求
3、客户端告诉服务端收到了第二次的tcp请求

例子【打电话】:
张三给李四打电话:【 张三是客户端 李四是服务端 】
1、喂,能听到我说话吗 【张三】
2、我可以听到。 【李四】
3、我有点事情跟你沟通一下。【张三】

tcp四次挥手: 【断开链接】
保证数据传输完成。
1、客户端告诉服务端说要断开链接
2、服务端告诉客户端说我准备一下
3、服务端告诉客户端说我已经准备好了
4、客户端断开了和服务端的连接

例子:
张三给李四打电话:【 张三是客户端 李四是服务端 】
1、我这边没事了,咱们断开吧。【张三】
2、行,那我想一下还有其他事情没有 【李四】

3、ok我这边也没有其他事情了,那咱们就挂了吧【李四】
4、我们就挂了吧 【张三】

php中打印http请求的头信息:
getallheaders

Array
(
# 客户端给服务端传递的cookie
[Cookie] => ‘’

# 通讯等语言
[Accept-Language] => zh-CN,zh;q=0.9

# 编码格式
[Accept-Encoding] => gzip, deflate

# 返回的内容是 html代码
[Accept] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

# 用户的头信息
[User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36

# 浏览器支持https请求
[Upgrade-Insecure-Requests] => 1

# 是否生成换成
[Cache-Control] => max-age=0

# 是否保持连接
[Connection] => keep-alive

# 请求的域名
[Host] => 1908api.phpclub.top

# 请求的主体的长度
[Content-Length] => 

# 请求的格式
[Content-Type] => 

)

状态码:
100: continue 继续,
200: ok 请求成功
301:永久重定向
302:临时重定向
403:forbidden。没有权限访问资源
404:not found。页面没有找到
419: token验证没有通过
500:internet error。 服务器内部错误,一般都是代码的错误
502: bad gateway 网关错误
504: gateway timeout 网关超时

1xx: 接收的信息正在处理
2xx: 成功处理
3xx: 需要其他处理
4xx: 服务器无法处理请求
5xx: 服务器出现问题

http请求分为 get post , get是请求数据,post是提交数据

get请求是直接发送到服务端。
	get请求传递数据最多是2kb,主要是通过url参数传递

而post请求分为2步: 【理论是没有上限的,可以修改配置文件,默认的上限是2m 】
	第一步是客户端告诉服务端说 限制要发送post请求,让服务端准备

		服务端如果准备好了,会返回一个状态100,代表服务端已经准备好了

	第二步: 是客户端发给post数据

理论上来说,post请求分为2步,而get请求可以直接请求数据,所以呢,get请求的速度是快于post的。

重定向:请求的资源没找到,告诉你一个新的地址,去请求新的地址。
临时重定向:一段时间内,去新的地址请求
永久重定向:把资源指向一个新的地址,以后请求都去新的地址请求。

http常见的版本:

http1.0: 每次http请求都需要三次握手
http1.1: 保持连接,【Connection: keep-alive】在一个连接上 可以发送多个http请求【默认时间是3s】
http2.0: 双向通信, 客户端可以给服务端发请求,服务端也可以主动给客户端推送数据。

七层协议:

应用层 【http】

表示层  【数据的转码 等】

会话层  [ 确定2个电脑之后如何进行会话,传输数据 ]

传输层 【 电脑和电脑直接如何传递数据  规定了两个电脑直接如何传递数据】

网络层 【电脑和电脑之间是通过ip进行通讯的 tcp/ip 】

数据链路层 【 对数据进行处理 变成01010 】

物理层 【电脑的硬件】

http协议是无状态、无连接的。 所以出现了会话控制。
会话控制:cookie和session,用来识别用户的

php运行的几种模式:

1、CLI server: php的命令行
2、apache模块
3、cgi和fastcgi

关于接口安全?

为什么要对接口进行安全加固?
1、接口是放在外网的,任何人都可以访问。
2、如果没有做安全加固的话,别人可能会恶意调用。
3、如果我们的数据直接明文传输,别人可以直接看到我们的数据,这样的话是不安全的 【数据的加密】

加密分为2种方式:

对称加密:
	使用相同的密钥和算法进行加密解密。
	
	常用的算法:
		DES、3DES、AES、

		TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES

	优点:
		算法公开、计算量小、加密速度快、加密效率高

	缺点:
		密钥管理比较复杂,如果调用多个接口,需要保存多个密钥。
		如果密钥丢失整个加密过程都是不安全的。


非对称加密:

	设计到公钥和私钥。公钥和私钥是唯一匹配的。

	常用的方式是: 
		(1)公钥加密 私钥解密
		(2)私钥加密 公钥解密

	使用的时候,服务端保存的是私钥,服务端把公钥给客户端。
		【 因为非对称加密中,是先产生私钥,拿着私钥去产生公钥。 】

	对于对称加密而言,双方的密钥相同,存在丢失或者是泄漏的情况,整个加密的过程都是不安全的。

	而非对称加密,服务端保存的是私钥,客户端保存的是公钥,客户端是根据公钥加密,只有服务端通过私钥进行解密。其他的人拿到公钥加密的数据,是没有私钥的,所以就算被别人拿到,也没有关系。

	优点:
		安全性更高

	缺点:
		加密效率低于对称加密
		对称加密的长度是由于限制的。
		密钥长度是1024的时候,最多只能加密117个字符

php实现对称加密要使用到的方法:

# 对称加密
openssl_encrypt();

openssl_decrypt();

php实现对称加密需要注意的问题:
密钥长度是1024的时候,最多加密117个字符,如果长度超过,需要分段加密,解密的时候也需要分段解密

加密的过程

1、先把数据进行加密 【加密之后可能会出现乱码】
2、对加密的数据进行了base64_encode

解密的时候:

1、先对加密的数据进行反编码 base64_decode
2、对base64_decode之后的数据进行解密

php实现非对称加密要使用到的方法:

# 公钥加密
openssl_public_encrypt();
# 私钥解密
openssl_private_decrypt();

# 私钥加密
openssl_private_encrypt();
# 公钥解密
openssl_public_decrypt();

非对称加密的结果是不一样的,而且长度也是固定的,对称加密的结果是一样的。

yum -y install lrzsz

sz 下载
rz 上传

在接口实现加密,如何去实现?

1、客户端进行加密 把加密的数据传到服务端
2、服务端进行解密

h5端加密 
API端解密

4月16日

注册接口怎么做?

1、注册的时候需要手机号
2、输入短信验证码

注册的时候为什么要短信验证码?
为了防止别人恶意注册,必须正确填写验证码才能注册成功。

短信验证码存入哪里比较合适?
建议存入数据库、也可以存入redis
手机号。 用户id 验证码
13261477141 1234

如何防止用户恶意的调用短信接口?
1、限制一分钟只能发一次。【通过后台去限制】

如何防止用户恶意调用接口?

1、限制的请求来源只能是本站,csrf
2、ip限制
3、验证码 【可以防止程序恶意的调用接口,刷短信验证码】

API如何实现注册?

1、发送验证码。接口
2、注册接口 
3、图片验证码接口
4、获取图片验证码的接口

1、图片验证码接口是在H5(客户端)还是API(服务端)写?

1、为什么要有图片验证码?
	为了防止发送短信的接口被恶意调用。

2、如果是在客户端写图片验证码接口,服务端的发送接口还是可以正常调用的
	所以验证码是在服务端生成的。

总的来说,验证码接口应该放在服务端。

php生成图片验证码的方法: GD2

php实现图片验证码的流程

【session是基于cookie的,session是存在cookie中的,cookie是可以写在浏览器上的 】
1、生成一个随机数
2、把随机数记录到session中
3、把图片验证码展示出来
4、用户输入图片验证码,把用户输入的验证码和session的验证做对比

cookie被禁用之后 可以通过url传参数的方式进行使用session

session_start 开启session

session_id 获取当前会话的 sessionid

先开启session_start ,在使用session-id 代表的是获取sessionid

如果先试用sessionid 在使用sessionstart。代表的是 设置当前会话的sessionid

原生的php

// $sid = $request -> get(“sid”);

// var_dump($_GET);

// var_dump($sid);
// # 测试原始php的sessionid传递
//
// session_id( $sid );
//
// session_start();

// $sid = session_id();

// $_SESSION[‘user_name’] = ‘zhangsan’;

// var_dump( s i d ) ; / / / / v a r d u m p ( sid); // // var_dump( sid);////vardump(_SESSION);

// exit;

laravel写法

$request -> session() -> setId( $request -> get(‘sid’) );

$request -> session() -> start();

$sid = $request -> session() -> getId();

var_dump($sid);

$request -> session() -> put(‘user_name’ , ‘zhangsan-123’);

var_dump($request -> session() -> get(‘user_name’));

###################################################################################################

API如何实现验证码呢?

1、为了区分不同用户的图片验证码,我们需要在图片验证上加一个唯一表示【需要session通过url传参的方式传递到服务端】

2、因为每个图片都要标示出来,所需需要在API端生成一个唯一的标示 【可以使用sessionid,因为sessionid是不会重复的】

3、H5需要获取到这个唯一标示,所以我们需要在写一个接口,去获取这个唯一表示。 【 获取图片验证码的地址的接口 】

###################################################################################################
zhangsan。 12345。 1111
lisi 23456。 2222

短信接口的地址:

https://market.aliyun.com/products/56928004/cmapi023305.html?spm=5176.2020520132.101.7.791372187l0Zqa

注册接口

1、接受用户名密码
2、接收验证码
3、验证验码是否正确
4、正确的话
5、验证手机号是否存在
6、不存在吧用户写入数据
7、存在提示错误信息

BUG:
验证输入正确之后,如果不点击切换,或者是刷新,验证码对应的内容是不会发生变化的。
1、在客户端添加判断,如果发送成功,更换验证码
点击发送之后,如果发送成功,吧验证码更换一张。 【服务端的图片验证码还是不会变的】

2、短信发送成功之后,在服务端吧验证码删除即可。

接口的数据签名:

#为什么要做接口签名?

防止数据被篡改

1、主要为了防止别人在拦截到请求之后,可能会被篡改。

怎么去实现签名?

1、把客户端传递到数据通过 md5的方式,生成一个签名.

2、客户端把签名传递到服务端。

【验签】3、服务端根据客户端传递到数据,生一个对应的签名
【验签】4、对比服务端和客户端的签名,如果一样的话,说明没有被修改,如果不一样说明数据在传输的过程中被修改过。

签名的具体实现:如何生成签名。

1、拼接接口需要的参数。

2、对接口的数据按照key进行字典排序。【ksort方法】

3、把数组转换成key1=value1&key2=value2&key3=value3这样的字符串

4、对字符串进行Md5加密,把签名传递到服务端去

5、服务端进行验签。

6、验签通过正常访问接口,不通过返回验签失败

签名算法泄漏之后如何保证签名的安全?

签名算法泄漏的话,意味着别人也可以生存一个正确的签名。

解决办法:
	在微信公众号开发的时候,申请测试号的时候 ,每个测试号都有一个 appid 和 appsecret。后边有一些接口都适用到了这些信息。

我们做的时候如何解决?

	1、给调用接口的每个客户端下发一个appid和appsecret

	2、在请求接口的参数中多加入一个参数 appid

	3、拼接接口需要的参数。

	4、对接口的数据按照key进行字典排序。【ksort方法】

	5、把数组转换成key1=value1&key2=value2&key3=value3这样的字符串

	6、把生成好的字符串,在后边追加 “&app_secret=服务端下发的密码”

	7、对拼接好的字符串进行Md5加密,把签名传递到服务端去

	8、服务端接受到数据之后,根据传递的appid 可以获取到对应app_secret

	9、和客户端一样的方式,生成一个服务端的签名,

	10、把服务端的签名 和 客户端的签名 做一个对比,如果一样正常请求,如果不一样说明数据被篡改了

全局变量

$a = 100;

function a( &$a )
{
# 局部变量
$a = 1000;
echo $a;
}
echo ‘
’;
echo $a;
exit;

&符号代表的是按地址传值。指的是 去的同一个内存地址,如果修改了内存中的值,两个变量都会改变。

接口防刷

为什么要做接口防刷?

1、防止别人恶意的去调用我们的接口。
2、如果有大量的访问会导致整个接口服务器压力过大宕机不能访问。
3、限制服务器的访问次数,保护服务器资源。

如何对接口进行防刷限制?

1、IP限制。
获取请求我们接口的ip,对ip进行限制【1分钟最多访问100次】

2、使用UA进行限制 【user-agent 用户头信息】

3、使用特殊的唯一表示
给每个调用接口的客户端下发一个唯一表示,客户端调用接口的时候,必须传递唯一标示。通过唯一表示进行限制

4、可以做一个类似微信公众平台 access_token的令牌。

实现一个功能,限制接口的访问次数,1分钟只能访问100次接口,如果超过100次,吧ip加入黑名单中,半小时之内不允许访问接口。

接口防刷通过Redis进行限制。

实现思路:

1、用户在访问接口的时候,获取用户的ip
	$request -> ip();

2、把ip作为key,访问次数作为对应的值,每次访问接口累加访问次数即可。

	【注意一个问题:key的有效期是1分钟,必须是第一次写入的时候 指定1分钟的有效期】

3、下一次访问的时候,判断是否超过100次,如果超过的,吧ip加入黑名单中半个小时。
	【用的数据类型是有序集合】

4、用户再访问的时候,判断他的ip是否在黑名单中,如果在黑名单,就不允许访问

5、需要注意,我们只是吧这个ip放入黑名单半个小时。
	【 用户ip进入黑名单的时间,只有半个小时,如果超过半个小时 需要从黑名单移除这个ip 】

Redis 如何设置密码:

找到redis的配置文件,设置redis的密码:
requirepass likang

redis常见的数据类型:

1、字符串
2、hash
3、set 
4、有序集合 zset
5、list 

集合中的数据不可以重复,有序集合支持排序操作。

集合: [ 元素,元素不能重复 ]
1908phpA
likang
yangwenli
xuluhao

有序集合:[可以设置有效期] 【 元素,但是多存储了一个元素对应的值 】
1908phpA
likang 18
yangwenli 19
xuluhao 20
chaihuimin 22
zhangdonglei 25

black_list : -> 不能设置有效期 ->
192.168.1.250 12:00
192.168.1.251 12:10

redis安装:
1、先安装redis服务。
2、安装php操作redis的扩展

一分钟统计ip访问次数,可能会存在的问题?

比如说我们在12:00:01的时候,访问1次,在12:00:59访问了98次,这样的话是没有到100次的,在12:00统计的数据,在12:01之前就过期了。
继续在12:01:01在去访问99次,也没有达到限制的100次。
这样的话,在12:00:59到12:01:01这三秒钟超过了100次。这样的话 限制就不存在意义了。

如何解决按分钟统计出现的问题?

一、分开统计访问次数:
1、把一分钟分为6段,每段分别统计访问次数
2、每次再算访问次数的时候,统计出当前的时间端的访问次数
3、在向前去前5段时间的访问次数,吧这6段时间加起来
4、判断是否超过我们的限制,如果超过加入黑名单

二、令牌桶
1、在redis中设置一个集合,集合中存在10个元素
2、客户端每次调用接口的时候,从集合中取出一个值
3、如果能够正常去到值,说明正常,允许访问
4、如果没有取到,说明限制令牌桶是空的,则不允许访问
5、每隔10s中给集合中添加10个元素 【 不是每次都写10个元素,而是把集合补够10个数字即可 】

#安装redis服务

1、下载redis的安装包
wget http://download.redis.io/releases/redis-5.0.8.tar.gz

2、解压压缩包
tar -zxvf redis-5.0.8.tar.gz
cd ./redis-5.0.8

3、把redis移动到 /usr/local/redis,并且跳转到/usr/local/redis
mv ./redis-5.0.8 /usr/local/redis
cd /usr/local/redis

4、安装redis
make
make install

5、启动redis
/usr/local/redis/src/redis-server /usr/local/redis/redis.conf &

6、关闭redis
killall redis-server

7、进入redis 命令行
/usr/local/redis/src/redis-cli

安装redis的扩展

phpize。动态安装php扩展的工具

1、先查看一下redis扩展是否安装

php -m | grep redis

2、没有安装redis的话,需要去下载php的redis扩展
http://pecl.php.net/package-stats.php

3、打开页面搜索redis

4、根据自己的php版本下载对应的扩展
查看服务器上的php版本
php -v

5、找到合适的版本进行下载

wget http://pecl.php.net/get/redis-5.2.1.tgz

6、解压压缩包,跳转到redis扩展的目录下
tar -zxvf redis-5.2.1.tgz
cd redis-5.2.1

7、在redis源码目录下执行 phpize
/usr/local/php/bin/phpize

8、执行检测是否可以安装,并且制定php-config的路径
./configure --with-php-config=/usr/local/php/bin/php-config

9、编译
make

10、编译安装
make install

11、找到php.ini 开启php的扩展
vim /usr/local/php/etc/php.ini
搜索extension
在普通模式下输入 / + 要搜索的关键字 回车
n 继续查找下一个。N查找上一个

12、找到对应扩展配置块 ,添加一行
extension=redis

13、重启php-fpm
killall php-fpm
/usr/local/php/sbin/php-fpm

接口鉴权的实现。

【 微信公众号开发的时候,不同类型的公众号有不同的权限。 】

如何实现:
借助了appid和appsecret。

接口如何实现鉴权?

1、给每个客户端下发一个appid和appsecret
2、接口端给每个客户端设置不同的权限
3、客户端请求接口的时候,接口端根据客户端传递的appid,找到客户端对应的权限
4、判断用户是否具备调用该接口的权限。

接口的重放攻击

重放:多次循环 ,一件事情做了很多次

接口的重放攻击:

客户端调用接口的时候,请求接口的数据,被第三方拿到,而且这个数据是正确的。

第三方就拿着这个正确的数据,一直频繁的去调用接口,导致接口服务器压力过大,甚至出现宕机。

如何防止重放攻击?

把请求记录下来,下次来的时候,判断请求是否已经处理过,处理过的话,给出的提示即可。

通过Redis解决

解决办法:

1、让客户端调用接口的时候,多传递2个参数, 时间戳和随机数

2、服务端去接收这2个参数,把这2个参数存入redis中。【 把时间戳和随机数拼接到一起,存入redis的集合 】

3、如果能够存储成功,说明是正常的请求

4、如果存入redis失败,说明不是正常的请求,返回提示信息

如何去实现?

1、在H5调用接口的时候,多加2个参数 【时间戳和随机数】

2、服务端接受 时间戳和随机数

3、写入redis的集合

4、写入成功说明正常,如果写入不成功,说明接口请求重放。

接口

接口的地址
接口的参数
返回的数据

Restful接口设计风格。

关于API接口设计的一个规范。只要符合这种规范的接口,我们都可以称之为。Restful接口。

1、协议

http或者https,建议使用https

https: http + ssl 都证书认证。

2、域名,建议使用单独的域名。 1908api.phpclub.top

https://api.phpclub.top

3、版本。
【因为app会存在多个版本,所以服务端的接口也可能存在多个版本。所以在接口要体现出来她的版本】
(1) header头添加一个版本号
(2) 在url中添加版本号的概念/ 建议使用它

https://api.phpclub.top/v1

4、 资源抽象【路径】
【把数据抽象成资源】
在我们的接口中会把所有的数据都想成资源【resource】。

例子:
	数据库中存在用户表。
	吧用户抽象成 用户的资源。

按照前4个规则来说,一般情况我们api的url就说,用户相关的接口我们的url就是: 
	https://api.phpclub.top/v1/user
商品的相关的接口
	https://api.phpclub.top/v1/goods
订单的相关的接口:
	https://api.phpclub.top/v1/order

5、不同的请求方式,代表不同的操作
【通过对资源的操作去操作我们的数据库】

http请求的场景的几种方式:
	get : 查找资源,查询数据  https://api.phpclub.top/v1/user  代表的是 获取用户的数据
	post : 新增一个资源,新增一条数据  https://api.phpclub.top/v1/user  代表的是 新增用户的数据
	put: 更新资源。https://api.phpclub.top/v1/user/1   修改的时候修改一个资源,需要跟上id,这个url代表的是 修改用户id为1的数据
	Patch: 更新资源。https://api.phpclub.top/v1/user/1   修改的时候修改一个资源,需要跟上id,这个url代表的是 修改用户id为1的数据
		区别:两个都是更新,put需要传递完整的数据。patch 只需要传递要修改的数据
	delete: 删除资源。https://api.phpclub.top/v1/user/1   代表的是删除用户id为1的这歌资源,实质上是删除用户id为1的数据

# 找到user中 年龄是23的女生

	获取资源:  get方式

		https://api.phpclub.top/v1/user/age/23/sex/2

	另外的一种方式:

		https://api.phpclub.top/v1/user?age=23&sex=2

6、对同一个url发送不同的请求,代表的是不同的操作。

Restful接口设计风格:

它是一个接口设计的规范,接口建议使用的协议是https,在url中最好能够体现接口的版本,restful接口风格讲的是资源抽象的概念【抽象成名词】,把我们相关的数据抽象成资源,通过http常见请求方式,进行对资源的操作。get请求对应获取资源,post新加资源,put修改资源,delete删除资源。

只要符合这种接口设计风格的接口,我们都可以称它为Restful风格的接口。

列表类的接口如何实现?

1、普通分页如何实现的
(1)接受页码,每页显示条数
(2)计算出偏移量 偏移量 = ( 当前页码 - 1 ) * 每页条数
(3)去数据库查询 select * from user limit 偏移量,每页条数

2、接口如何实现分页?
接口地址 http://1908api.phpclub.top/Account

(1)确定要查询的数据[ user ]
(2)接受page参数,在接受每页条数
(3)计算偏移量
(4)取出数据
(5)返回给客户端

login接口?

客户端:
user_name:zhangsan
password:123456

服务端:
user_name:zhangsan
password:123456

接口安全:
加密 【加密】 讲过了
签名以及验签 【签名】
防刷
鉴权
接口重放攻击
接口幂等性

#############################################################################

1、关于用户令牌验证。

我们之前在登录完成之后会下发一个token。
token是验证用户是否登录的。

2、令牌是什么时间产生的?

令牌是在用户登录成功之后产生的,用来记录用户的登录状态。

3、客户端把令牌存在那里?

session和cookie时间基于浏览器的,如果我们现在是给app提供的接口的话,是没有办法使用session和cookie

所以app记录登录状态需要把 令牌记录下来,可以存文件或者内存,建议使用文件存储。

4、我们现在的项目分为H5 和 api, 用户登录成功之后,生成了令牌和用户id绑定到一起。

我们可以把这些数据存到我们的session。

5、API端关于用户是否登录的验证,如果用户是调用登录之后才能访问的接口,API必须验证令牌是否正确。

要求 客户端调用相关接口的时候,必须传递user_id和token,API验证用户id和token是不是正确,如果
正确才能访问相关的数据。

############################################# 图片上传接口################################################
【上传用户的头像为例】

1、如何实现图片上传接口。

(1)我们把头像保存在h5端可以吗?

	头像不能保存在h5端,因为用户在客户端要查看的时候,不能去访问h5端的链接。
	头像应该放在外面的API端。

(2)用户如何去上传头像
	在用户的个人中心页面让用户点击可以上传头像。

(3)流程
	1、在h5端上传头像
	2、上传成功,把头像保存在h5项目下的文件夹中
	3、因为头像要保存在api端,所以需要把h5下文件夹中的头像通过图片上传接口,上传到api中
	4、api返回一个可以访问的路径,h5端展示用户头像的时候,用image标签展示出来接口即可。

2、需要在API端写一个文件上传的接口

文件上传的几种方式:
	1、二进制。 【二进制在http传输中可能会出现乱码,所以不建议使用】
	2、普通文件上传
	3、base64_encode方式上传文件 【 API使用比较多的 】

3、API端文件上传接口如何实现?
1、上传头像的时候,是 把剪切完的头像上传到了h5项目下
2、h5去调用API上传接口,把图片的内容和格式告诉API
3、API保存图片,把用户的头像更新一下,保存到数据库
4、API给H5返回一个路径

4、修改头像接口【图片上传接口】需要的参数

1、user_id  + token
2、 image_type
3、 image_base64_encode

在APi的域名中添加header

location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
# 设置允许通过http://1908h5.phpclub.top访问本域名下的图片
add_header Access-Control-Allow-Origin ‘http://1908h5.phpclub.top’;
expires 30d;
access_log off;
}

########

ln 建立链接

ln -s 建立软链接 [类似于windows下的快捷方式]

ln -s 被链接的目录 链接的目录

ln -s …/resource/userhead ./userhead

链接的目录 不存放文件的,只是建立了一个快捷访问方式。

getimagesize : 获取图片的信息,长和宽,还有类型

你可能感兴趣的:(API的小结,api)