scheme://user:password@host:port/path?query#fragment # 一个具体的例子 https://user:pass@www.example.com:8080/api/v1/users/?page=2&limit=10#info
| 部分 | 作用 | 举例 |
|---|---|---|
| 1. scheme(协议) | 指定使用的协议,告诉浏览器怎么访问资源 | http / https / ftp |
| 2. user:password(可选) | 用户名和密码,通常用于基本认证(不常用) | user:pass@ |
| 3. host(主机名或IP) | 服务器地址,域名或 IP | www.example.com / 127.0.0.1 |
| 4. port(端口号,可选) | 服务器端口号,省略时用默认值 | :80(HTTP) / :443(HTTPS) |
| 5. path(路径) | 服务器资源路径(路由) | /api/v1/user/ |
| 6. query(查询参数) | 传递给服务器的参数,键值对形式 | ?page=2&limit=10 |
| 7. fragment(锚点) | 客户端页面内定位,服务器不解析 | #section3 |
一般来说:在做backend开发的时候,和 URL 匹配真正相关的,只有「路径(path)」这一部分
使用Vue.js等前端框架开发单页应用的时候,因为是前后端分离,所以实际上在浏览器地址栏的url是不会发送给服务器的
个人的简单理解:
可以看出:
其他补充:
前端需要做什么?
客户端无需手动发起“检查跨域是否可用”的请求——浏览器会根据请求内容自动判断是否需要进行 CORS Preflight(预检)请求。
后端大概的处理逻辑可能这样:
// 后端并不需要、也不应该返回整个白名单 // 只需判断请求来源是否在白名单里,如果是,就回显该来源,否则不返回 Access-Control-Allow-Origin const whitelist = [/* 完整 origin 列表 */]; const origin = req.headers.origin; if (whitelist.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Credentials', 'true'); // 其他 CORS 头... }
后端的返回内容可能类似这样:
Access-Control-Allow-Origin: https://www.front.example.com Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Allow-Credentials: true Vary: Origin
前提:我们确保HTTPS是安全的,可以发送一些敏感信息(密码、Token之类的)。虽然应该尽量减少发送次数,或者避免直接明文发送,但是基于HTTPS发送是没有问题的(否则就无法进行下一步了)。
既然HTTPS是安全的,那么基本上,每次请求都把用户名和密码都带上也可以(不安全,或者说不太安全,但是可行),这就是最基础的认证方式,每次请求都带上用户名和密码。
那么实现认证还有哪些其他思路呢?
1 Cookie,第一次发送用户名密码,通过验证后服务器生成Cookie,然后客户端和服务器都保存,每次请求都发送Cookie,服务器接收到请求信息后,查询数据库,验证此Cookie。缺点:每次都要查询数据库,服务端要记录这个Cookie。优点:服务器可以随时撤销这个Cookie(从数据库中删除)。
2 Token(单个JWT,JSON Web Token),第一次发送用户名密码,通过验证后服务器生成Token,Token中包含用户信息(未加密),并且可以验证此Token是否是由服务器生成的,由此,服务器就不用存储Token了,每次接收到请求后,不用查询数据库,也可以判断此Token是否合法。优点:减少了对数据库的访问,适合微服务。缺点:Token一旦生成就不方便撤销了,只能等到Token过期;如果Token泄漏了就不安全了,如果想要实现服务器随时可以撤销Token,就需要记录一个Token的黑名单。
3 Token(两个JWT),客户端发送用户名密码,服务器验证通过后,生成Refresh Token,服务器也要记录此Token,同时发给客户端。客户端将Refresh Token发送给服务器,服务器验证OK后,生成Access Token,此Token有效期很短(几小时),并且服务器不记录。此后,每次请求,客户端会附带上Access Token,服务器也只验证Access Token,如果过期,客户端再重新申请。分析:如果Access Token泄漏,因为有效期比较短,所以可以尽可能得降低风险;如果Refresh Token泄漏,客户端可以请求注销此Token,因为服务器也保存了Token,所以从数据库中删除就可以了。另外,这种做法也降低了访问数据库的请求次数。
4 OAuth 2.0:还在学习中,不是特别理解。
AI:OAuth 2.0 是一个授权协议(Authorization Protocol),它的核心目的是:让用户授权第三方访问自己的资源,而不泄露密码。
看到这种解释,首先想到的是「Login with Google」之类的功能,但是实际上「第三方」也不一定真的是「第三方」:比如同一个公司的多个应用使用相同的账户登录,那么这个账户系统就可以独立出来,其他的应用都被看作是「第三方」(但实际上是同一个公司的产品)。
还是基于Token的认证流程,只不过是流程复杂一些。
5 OpenID Connect(OIDC):学习中
补充:
关于认证的信息,一般都会放在HTTP头部中的Authorization字段,比如
Authorization: Bearer <token>
CSRF(Cross‑Site Request Forgery):跨站请求伪造
前端可用的库:i18next, Vue I18n等
在某些情况下,后端也需要做国际化?