我目前正在构建一个Web应用程序,它是一个AngularJS前端,它与使用Laravel构建的RESTful API进行通信 . 我取得了很好的进展,但发现很难理解如何处理用户身份验证 .
我决定使用它,因为它对我来说也可能是一次学习经历 . 我用来处理这个的包是oauth2-server-laravel .
基本用户故事是用户可以为应用程序注册他们的用户名/密码组合,然后他们使用相同的用户名和密码登录应用程序 . 它们仅通过用户名和密码进行身份验证,而不是通过任何客户端密钥进行身份验证 . 登录后,应为他们提供一个访问令牌,该令牌将与每个将来的请求一起发送,以在不同的API endpoints 上对其进行身份验证 .
OAuth2库有一个"password flow" grant类型,这似乎是我需要的,但它也需要 client_id
和 client_secret
参数,我不想要 . 请求URI是这样的:
POST https://www.example.com/oauth/access_token?
grant_type=password&
client_id=the_client_id&
client_secret=the_client_secret&
username=the_username&
password=the_password&
scope=scope1,scope2&
state=123456789
但我想要的只是:
POST https://www.example.com/oauth/access_token?
grant_type=password&
username=the_username&
password=the_password
我是如何提供尚未进行身份验证的用户的客户端ID和秘密?
是否有我可以使用的不同授权,或者我想要实现的根本不适合OAuth?
3 回答
请注意,
client id
和client secret
不是您必须强制最终用户通过的参数 . 它们是静态的,并在/为您的客户端应用程序定义(在这种情况下为角度应用程序) .您需要做的就是在
oauth_clients
表中为主应用程序创建记录,并在oauth_scopes
表中创建具有完全访问权限的作用域,并在请求令牌时发送此值 .事实就是这样 .
此外,您可能需要考虑在构建仅限js的应用程序时使用隐式授权流,因为在js应用程序中存储客户机密钥和刷新令牌是不安全的 . 在最终产品中使用隐式授权可能看起来像soundcloud上的登录窗口,并且更安全,因为在服务器端获取令牌而不暴露客户端密钥 .
另一种方法,如果您仍想使用密码流,则需要创建代理以刷新令牌 . 代理可以在加密的纯http cookie中隐藏您的刷新令牌,并且您的js-app不会向您的api请求新令牌,而是请求代理 . 代理从加密cookie中读取刷新令牌,向api请求新令牌并将其返回 . 因此,刷新令牌永远不会暴露 . 如果你设置令牌ttl一小时让我们说,那么在正常应用的情况下窃取令牌将是非常“毫无意义的”,并且窃取刷新令牌将是“不可能*” .
*当然,如果有人真的想要他可能会以任何方式破解它 .
是的,我知道这一切看起来有点hacky - 模式窗口登录,代理等 . 但也搜索这个主题,我找不到更好,更优雅的方式做到这一点 . 我认为如果你想要一个基于令牌的身份验证,所有js-apps仍然需要处理 .
你遗漏了OAuth规范 . 在使用OAuth v2的密码方法时,在要求访问令牌时,
client_id
和client_secret
非常重要 . 实际上,它们对于为您提供访问令牌的每种方法都很重要 . 它们标识应用程序或执行请求的服务器 .例如,假设您拥有API,2个移动应用程序和另一个使用API执行某些任务的服务器 . 您将使用自己的
client_id
和client_secret
创建3个客户端 . 如果您的应用程序具有各种访问级别(在OAuth v2中称为scopes
),则对应于其他服务器的client_id
将能够调用需要范围admin
的API函数,而您的移动应用程序将只能调用如果您已定义此类范围,则需要basic
范围的API .如果您的API在未来成长,这非常重要 . 另一个例子,让我们假设你已经给你的一个朋友提供了一个API密钥(一对
client_id
和client_secret
),他已经用你的API Build 了一个漂亮的移动应用程序 . 如果有一天他开始用你的API做顽皮的事情,你就不能轻易地阻止他 . 如果您遵循OAuth v2原则,您可能刚刚删除了他的密钥对 .在开发API之前,OAuth v2并不容易理解,花时间阅读规范和优秀的教程 .
一些有用的链接:
官方RFC:http://tools.ietf.org/html/rfc6749
一个教程在Tutsplus:http://code.tutsplus.com/articles/oauth-20-the-good-the-bad-the-ugly--net-33216
只是为plunntic的优秀答案添加一点:记住“客户端”与“用户”无关,所以当我使用密码流时,我只需将client_id和client_secret定义为AngularJS应用程序上的常量,告诉api后端:嘿,这是用于请求令牌的浏览器应用程序 .