token认证

token认证

文章出处:https://segmentfault.com/a/1190000014527692

一、CSRF是什么?

  CSRF(Cross-site request forgery),中文名称:跨站请求伪造。攻击者盗用你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

二、CSRF攻击原理

三、防御CSRF的策略:token认证

1、token验证方法

  (1)、CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

  (2)、这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>,这样就把 token 以参数的形式加入请求了。但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。

  (3)、该方法还有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在自己的网站上得到这个 token,并马上就可以发动 CSRF 攻击。为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加。不过,即使这个 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。

2、token产生

  Token是在服务端产生的。如果前端使用用户名和密码向服务端发送请求认证,服务端认证成功,那么在服务端会返回Token给前端。前端可以在每次请求的时候带上Token证明自己的合法地位。如果Token在服务端持久化,那他就是一个永久的身份令牌。

3、Token设置有效期

  Q: 用户在正常操作的过程中,Token 过期失效了,要求用户重新登录……用户体验会很糟糕。

  A: 方法一,使用 Refresh Token。这种方法中,服务端不需要刷新 Token 的过期时间,一旦 Token 过期,就反馈给前端,前端使用 Refresh Token 申请一个全新 Token 继续使用。这种方法中,服务端只需要在客户端请求更新 Token 的时候对 Refresh Token 的有效性进行一次检查,大大减少了更新有效期的操作,也就避免了频繁读写。当然 Refresh Token 也是有有效期的,但是这个有效期就可以长一点了,比如,以天为单位的时间。

  (1)实例如下:

//一般是登录时向服务器发请求获取到Token
function login(username,password){
    var param = {"username":username,"password":password};
    $.post("/api/v1/login",param,function(data){
        //将response得到的Token缓存到sessionStorage里面
        sessionStorage.setItem(‘Token‘,data.TOKEN);
    }).error(function(error){
        alert(JSON.parse(error.responseText).errorMsg);
    })
}

//登录事件
$("#login").click(function(){
    var username=$(‘input[name=username]‘).val();
    var password=$(‘input[name=password]‘).val();
    login(username,password);
})

  (2)token请求验证:

    客户端拿sessionStorage中存储的Token去向服务端进行验证:

 function ajaxRequest = function(option) {
    $.ajax({
      url: getDmsFuncIdUrl(newUrl, currentToken),
      type: option.type,
      data: option.data,
      dataType: "json",
      async: option.async != undefined ? option.async : true,
      cache: false,
      beforeSend: function(xhr) {
        xhr.setRequestHeader("Accept", "application/json;charset=UTF-8");
        //设置数据格式:发送json格式数据,并带有字符编码:"charset=UTF-8"
        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        //将Token放在请求头header中,此处格式与后台一一对应。
        xhr.setRequestHeader(
          "Authorization",
          "Bearer " + getParamsStorage("Token")
        );
        if (option.beforeSend) {
          option.beforeSend(xhr);
        }
      },
      success: function(data, textStatus, jqXHR) {
        //结束ajax请求
        ajaxRestEnd(option);
      },
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        //结束ajax请求
        ajaxRestEnd(option);
      }
    })
  };

  如下图:

  注意:图中定义的Token验证接口(只要是请求的 "http://${spring.cloud.client.ipAddress}:${server.port}/xxx" 这个端口号下的任何路径都会先进行Token验证的),请求参数为Content-Type和Authorization,且Authorization的请求数据格式为:Authorization : Bearer token,所以我们上面的代码是: xhr.setRequestHeader("Authorization","Bearer " + getParamsStorage("Token"));

  (3)总结:

    这样我们每次的请求都调用 ajaxRequest 方法即可,即在每次请求接口数据的的时候都会带上我们登陆后获得的Token值,这样就能通过服务器的验证,打开服务器的大门,进而进行不同接口数据的调用啦!是不是很清楚呢~~~

  (4)Refresh Token

    一般是在获取页面的公共常用数据的时候刷新Token值

//刷新Token
  function refreshToken() {
    dmsCommon.ajaxRestRequest({
      url:"/api/v1/login/refreshToken",
      type: "GET",
      async: false,
      sucessCallBack: function(data) {
        currentToken = data;
      }
      });
    }

  //每5分钟刷新一次token 值
  function refreshTokenInterval() {
    setInterval(refreshToken, 5 * 60 * 1000);
  }

  //初始化常规数据
  function getMainnData(){

    // coding

    //进行定时刷新
    refreshTokenInterval();
   }

  借鉴大牛的文章,浅显易懂, URL: https://segmentfault.com/a/1190000013010835

原文地址:https://www.cnblogs.com/parable/p/11232598.html

时间: 2024-10-10 18:13:41

token认证的相关文章

微信token认证源码分享(c#版)

在开发时遇到一个问题: 上线后提交申请微信提示"您的服务器没有正确响应token验证...",我查看日志发现根本就没有接收到来自微信的参数. 后来我又记录了微信请求方式和请求的字符串,想看看微信服务器到底有没有给我的服务器响应请求.结果是有的.并且通过了. 代码就添加了Request.HttpMethod和Request.QueryString没变,但不晓得怎么回事. /// <summary> 按照api说明对signature进行校验,校验成功返回参数echostr &

flask token认证

在前后端分离的项目中,我们现在多半会使用token认证机制实现登录权限验证. token通常会给一个过期时间,这样即使token泄露了,危害期也只是在有效时间内,超过这个有效时间,token过期了,就需要重新生成一个新的token. 如何生成token呢? 1.创建用户数据库,本文会使用flask-SQLAlchemy(ORM)去管理数据库: 首先创建一个用户模型:包括了用户昵称,账号(邮箱或者电话号码等),密码及拥有的权限 1 class User(Base): 2 id = Column(I

034.认证方式 | Token认证 及 AK/SK认证

认证方式 关于认证: https://www.cnblogs.com/badboyh2o/p/11068779.html https://www.cnblogs.com/badboyh2o/p/11069470.html Token认证 用途:一般用于登录,token包含授权信息. 原理:任何请求,都附带token:服务端根据token判断请求是否合法. 缺点:如果报文在中途被劫持,那么token就泄露了,这时(token有效期内)黑客就可以构造任意的请求了. AK/SK的认证 用途:一般用于后

【django后端分离】Django Rest Framework之认证系统之redis数据库的token认证(token过期时间)

1:登录视图 redis_cli.py文件: import redis Pool= redis.ConnectionPool(host='localhost',port=6379,decode_responses=True) 登录视图文件:import redisfrom utils.redis_cli import Pool    # 创建redis连接池 class UserLogin(APIView): """ 用户登陆认证: 登录成功更新token值,并且返回给前端,

ASP.NET Core Token认证

翻译:Token Authentication in ASP.NET Core 令牌认证(Token Authentication)已经成为单页应用(SPA)和移动应用事实上的标准.即使是传统的B/S应用也能利用其优点.优点很明白:极少的服务端数据管理.可扩展性.可以使用单独的认证服务器和应用服务器分离. 如果你对令牌(token)不是太了解,可以看这篇文章( overview of token authentication and JWTs) 令牌认证在asp.net core中集成.其中包括

java微信二次第三方开发,token认证,消息事件接收,图文素材库,自定义菜单等功能

基于之前的文章SSM配置的项目:http://www.cnblogs.com/mangyang/p/5168291.html 来进行微信第三方开发, 微信二次开发,官方还是网上有很多介绍了,这里就不在进行讲述了 直接上干货. 首先 与微信对接,服务器配置,需要80端口和443端口开放的服务器,这里推荐 使用 python 的pagekite,一款反向代理的工具,具体安装百度搜,提供下配置放方法:http://jingyan.baidu.com/article/0eb457e52ca0af03f0

Restful下的token认证方案

Restful讲究一个无状态的特性(stateless),这就不能把一些例如登陆后的认证信息写进cookie的传统方式, 目前探索的是采用token的方式来进行权限的识别. 刚开始研究token的时候,很容易查到比较流行的JWT(JSON Web Token)的很多资料,目前有RFC的规范(尽管还只是个草案). 简单来说JWT规定了可以自定义的CLAIM区域,并且可以加密(要在头部指明加密方法),如下图所示 (本图来自于https://jwt.io) 由于采用的非对称加密的方式,所以一般情况下信

Aspnet前后端分离项目手记(二)关于token认证

在前后端分离的项目中,首先我们要解决的问题就是身份认证 以往的时候,我们使用cookie+session,或者只用cookie来保持会话. 一,先来复习一下cookie和session 首先我们来复习一下在aspnet中cookie和session的关系,做一个简单试验 这是一个普通的view没有任何处理 可以看到,没有任何东西(cookie),然后当我们写入一个session之后 \ 会发现多了一个名为ASP.NET_SessionId的cookie.我们都知道在aspnet中,session

Aspnet Mvc 前后端分离项目手记(二)关于token认证

在前后端分离的项目中,首先我们要解决的问题就是身份认证 以往的时候,我们使用cookie+session,或者只用cookie来保持会话. 一,先来复习一下cookie和session 首先我们来复习一下在aspnet中cookie和session的关系,做一个简单试验 这是一个普通的view没有任何处理 可以看到,没有任何东西(cookie),然后当我们写入一个session之后 会发现多了一个名为ASP.NET_SessionId的cookie.我们都知道在aspnet中,session是保