简体   繁体   English

REST API - 如何实现用户特定授权?

[英]REST API - How to implement user specific authorisation?

So I'm currently learning/building a REST API backend server for my web application using NodeJS, ExpressJS, and MySQL as the database. So I'm currently learning/building a REST API backend server for my web application using NodeJS, ExpressJS, and MySQL as the database. My question is in regards to the best way to implement authorisation to ensure User A does not access or edit the data belonging to another User.我的问题是关于实施授权以确保用户 A 不会访问或编辑属于另一个用户的数据的最佳方式。 Please note that I understand there are a lot of examples for implementation of role based authorisation (ie user groups vs admin groups, etc) but this is not what I'm asking.请注意,我了解有很多实施基于角色的授权的示例(即用户组与管理员组等),但这不是我要问的。 Instead, how do I authorise a user against the data they are accessing?相反,我如何授权用户访问他们正在访问的数据?

It is possible that I'm overthinking this and this is not even necessary;我可能想多了,这甚至没有必要; that I should just check whether the data belongs to the user in every SQL query, but I thought I'd ask if there's a middleware or policy architecture that takes care of this, or maybe even authorise through caching.我应该在每个 SQL 查询中检查数据是否属于用户,但我想我会问是否有中间件或策略架构来处理这个问题,或者甚至可以通过缓存进行授权。

The only solution I can think of is that every SQL query returns the the user id with the result, then I just create a service that checks every result if the id matches or not.我能想到的唯一解决方案是每个 SQL 查询都返回用户 ID 和结果,然后我只创建一个服务来检查每个结果是否匹配。 If yes, then proceed.如果是,则继续。 If not rollback the query and return unauthorised error.如果不回滚查询并返回未经授权的错误。 Is this ok?这个可以吗?

I very much appreciate your advice, help, and if you can point me in the right direction.我非常感谢您的建议,帮助,如果您能指出我正确的方向。

Many thanks in advance.提前谢谢了。

Save the userId (or ownerId) in every table, and create a middleware where each db access method requires the userId as a parameter, for example:在每个表中保存 userId(或 ownerId),并创建一个中间件,其中每个 db 访问方法都需要 userId 作为参数,例如:

readOne(id, userId) {
    // implements SELECT * FROM example WHERE id = id AND userId = userId
}

updateOne(id, data, userId) {
    // implements UPDATE example SET data = data WHERE id = id AND userId = userId
}
...

For security reasons, never send as a response "Requested data exist by you aren't the owner".出于安全原因,切勿将“您不是所有者请求的数据存在”作为响应发送。

The simplest things usually work best.最简单的事情通常效果最好。 You wouldn't have to have a special service for checking authorization rights for every entity and you can do it at data access level eg.您不必拥有检查每个实体的授权权限的特殊服务,您可以在数据访问级别执行此操作,例如。 SELECT * FROM foo WHERE user_id =:currentUser or UPDATE foo SET foo = bar WHERE user_id =:currentUser SELECT * FROM foo WHERE user_id =:currentUserUPDATE foo SET foo = bar WHERE user_id =:currentUser

It also depends whether you want to notify the user about unallowed access via HTTP401 or not to reveal that such a resource even exists for different user HTTP404.这还取决于您是否要通过 HTTP401 通知用户有关未经允许的访问,或者是否要显示对于不同的用户 HTTP404 甚至存在这样的资源。

For HTTP401 the scenario would be:对于 HTTP401,场景将是:

const entity = loadFromDB(id);
if(entity.userId !== currentUserId) { 
  res.send(401); 
  return;
}

... update entity logic ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM