筋斗云接口编程 / 函数型接口

编程入门 行业动态 更新时间:2024-10-26 08:30:46

筋斗云<a href=https://www.elefans.com/category/jswz/34/1771365.html style=接口编程 / 函数型接口"/>

筋斗云接口编程 / 函数型接口

如果不是典型的对象增删改查操作,可以设计函数型接口,比如登录、修改密码、上传文件这些。

函数型接口一般实现在文件 php/api_functions.php 中,它被主文件api.php包含。
假设有以下接口定义:

获取登录信息(who am i?)whoami() -> {id}应用逻辑
- 权限:AUTH_USER (必须用户登录后才可用)

我们使用模拟数据实现接口,函数名规范为api_{接口名}

function api_whoami()
{checkAuth(AUTH_USER);return ["id" => 100];
}

在api_functions.php中,作为示例,其中已经定义了登录、退出等接口,实际开发时在其基础上修改即可。
由于登录与权限定义密切相关,为了了解原理,我们清空这个文件,重新来写登录、退出接口。
同时学习获取参数、数据库操作等常用函数。

[任务]

本节要求实现登录、退出、取登录信息三个接口,设计如下:

登录接口

login(uname, pwd, _app?=user) -> {id, _isNew?}用户或员工登录(通过_app参数区分),如果是用户登录且用户不存在,可自动创建用户。参数
- _app: 前端应用名称,用于区分登录类型,"user"-用户端, "emp"-员工端。返回
- _isNew: 如果是新注册用户,该字段为1,否则不返回此字段。应用逻辑
- 权限: AUTH_GUEST
- 对于用户登录(_app是"user"),如果用户不存在,则自动创建用户。
- 密码采用md5加密保存

取登录信息

whoami() -> {id}如果已登录,则返回与登录接口相同的信息,否则返回未登录错误。
用户端或员工端均可用。
客户端可调用本接口测试是否可以通过重用会话,实现免登录进入。应用逻辑
- 权限:AUTH_USER | AUTH_EMP

退出接口

logout()退出登录。用户端或员工端均可用。应用逻辑
- 权限:AUTH_USER | AUTH_EMP

在接口定义中,一般包括接口原型,参数及返回数据说明,应用逻辑等。
对于含义清晰的参数和返回数据,也不必一一说明。
应用逻辑中应先规定该接口的权限。

权限定义

在实现接口前,我们先了解如何定义权限。

权限定义在接口应用的主文件api.php中,打开它我们能看到登录类型和权限类型的定义:

const AUTH_GUEST = 0;
// 登陆类型
const AUTH_USER = 0x01;
const AUTH_EMP = 0x02;
const AUTH_ADMIN = 0x04;// AUTH_LOGIN是一个特殊的权限,表示任一身份已登录。
define("AUTH_LOGIN", AUTH_USER | AUTH_EMP | AUTH_ADMIN);// 权限类型
const PERM_MGR = 0x08;
const PERM_TEST_MODE = 0x1000;
const PERM_MOCK_MODE = 0x2000;$PERMS = [AUTH_GUEST => "guest",AUTH_USER => "user",AUTH_EMP => "employee",AUTH_ADMIN => "admin",PERM_MGR => "manager",PERM_TEST_MODE => "testmode",PERM_MOCK_MODE => "mockmode",
];

上面按二进制位数不同,定义登录类型和各类权限,测试模式与模拟模式也可当作特殊的权限来对待。
在全局变量$PERMS中,为每个权限指定了一个可读的名字。

然后定义有一个重要的回调函数onGetPerms,它将根据登录情况、session中的数据或全局变量来取出所有当前可能有的权限,
后面常用的检查权限的函数hasPerm/checkAuth都将调用它:

function onGetPerms()
{$perms = 0;if (isset($_SESSION["uid"])) {$perms |= AUTH_USER;}else if (isset($_SESSION["empId"])) {$perms |= AUTH_EMP;}...if (@$GLOBALS["TEST_MODE"]) {$perms |= PERM_TEST_MODE;}...return $perms;
}

在登录成功时,我们应设置相应的session变量,如用户登录成功设置$_SESSION["uid"],员工登录成功设置$_SESSION["empId"],等等。

后面讲对象型接口时,还会有另一个重要的回调函数onCreateAC,用于将权限与类名进行绑定。

登录与退出

上节我们已经了解到,登录与权限检查密切相关,需要将用户信息存入session中,登录接口的大致实现如下:

function api_login()
{$type = getAppType();if ($type == "user") {... 验证成功 ...$_SESSION["uid"] = ...}else if ($type == "emp") {... 验证成功 ...$_SESSION["empId"] = ...}...
}

定义一个函数型接口,函数名称一定要符合 api_{接口名} 的规范。接口名以小写字母开头。
在接口实现时,一般应根据接口中的权限说明,使用checkAuth函数进行权限检查。

// 按设计要求,用md5加密后保存密码。
function hashPwd($pwd)
{return md5($pwd);
}function api_login()
{$type = getAppType();$uname = mparam("uname");$pwd = mparam("pwd");// 用户登录,如不存在则自动创建新用户if ($type == "user") {$sql = sprintf("SELECT id,pwd FROM User WHERE uname=%s", Q($uname));$row = queryOne($sql, PDO::FETCH_ASSOC);if ($row === false) {// 自动注册新用户$sql = sprintf("INSERT INTO User (uname, pwd) VALUES (%s, '%s')", Q($uname), hashPwd($pwd));$id = execOne($sql, true);$ret = ["id" => $id,"_isNew" => 1];}else if (hashPwd($pwd) != $row["pwd"]) {throw new MyException(E_AUTHFAIL, "bad password", "密码错误");}else {$ret = ["id" => $row["id"] ];}$_SESSION["uid"] = $ret["id"];}// 员工登录else if ($type == "emp") {$sql = sprintf("SELECT id,pwd FROM Employee WHERE uname=%s", Q($uname));$row = queryOne($sql, PDO::FETCH_ASSOC);if ($row === false || hashPwd($pwd) != $row["pwd"])throw new MyException(E_AUTHFAIL, "bad uname or password", "用户名或密码错误");$ret = ["id" => $row["id"] ];$_SESSION["empId"] = $row["id"];}else {throw new MyException(E_PARAM, "Unknown type `$type`");}return $ret;
}

在api_login函数中,先使用框架函数getAppType获取到登录类型(也称应用类型),再按登录类型分别查验身份,并最终设置$_SESSION相关变量,
这里设置的变量与之前的权限回调函数onGetPerms中相对应。

这里使用了很多常用函数,比如获取必需参数使用mparam函数,数据库查询使用了queryOne, execOne函数,出错返回使用MyException等,之后章节将详细介绍。

在实现whoami接口时,返回保存在会话(session)中的变量即可,logout接口则更加简单,直接销毁会话:


function api_whoami()
{checkAuth(AUTH_USER | AUTH_EMP);// 也可以用AUTH_LOGIN这个特殊的权限,表示任一身份已登录。// checkAuth(AUTH_LOGIN);if (hasPerm(AUTH_USER))return ["id"=> $_SESSION["uid"]];if (hasPerm(AUTH_EMP))return ["id"=> $_SESSION["empId"]];throw new MyException(E_SERVER);
}function api_logout()
{checkAuth(AUTH_LOGIN);session_destroy();
}

[应用标识与应用类型]

在筋斗云中,URL参数_app称为前端应用标识(app),缺省为”user”,表示用户端应用。

不同应用要求使用不同的应用标识,在与后端的会话中使用的cookie也会有所不同,因而不同的应用即使同时在浏览器中打开也不会相互干扰。

应用标识中的主干部分称为应用类型(app type),例如有三个应用分别标识为”emp”(员工端), “emp2”(经理端)和”emp-store”(商户管理端),
它们的主干部分(去除尾部数字,去除”-“及后面部分)是相同的,都是”emp”,即它们具有相同的应用类型”emp”。

函数getAppType就是用来根据URL参数_app取应用类型,不同的应用如果是相同的应用类型,则登录方式相同,比如上例中都是用员工登录。

更多推荐

筋斗云接口编程 / 函数型接口

本文发布于:2024-02-10 16:26:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1676217.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:接口   函数   筋斗云

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!