Totato5749
V2EX  ›  Android

求教, Android 如何实现 Token 过期后重新获取并重新进行之前的操作

  •  
  •   Totato5749 · Jun 14, 2016 · 20797 views
    This topic created in 3621 days ago, the information mentioned may be changed or developed.

    公司的项目,用户在客户端登陆后后台会给用户一个 token ,以后每次执行与用户身份有关的操作都需要向服务器带上这个 token,这个 token 在一定时间后失效,这时进行与用户身份有关的操作时会返回 token 过期错误提示。

    之前我在处理这个问题时,遇到操作返回 token 过期错误,我会让用户强制重新登录。不过这个处理对用户来说体验很差,基本相当于每天都要重新登录。

    token 过期有以下几个原因:

    1. token 时间到期
    2. 用户在其他设备登录,原来设备中的 token 就会过期
    3. 其他异常等

    我想要实现的功能是: 在某次网络操作时,当服务器返回 token 过期错误后,如何实现重新获取 token 后再次尝试之前的网络操作,不让用户察觉到中间的断裂感。

    求各位大侠指教,小弟跪谢

    14 replies    2016-06-15 10:26:21 +08:00
    Ouyangan
        1
    Ouyangan  
       Jun 14, 2016
    那就自动帮用户登录一次 .
    Totato5749
        2
    Totato5749  
    OP
       Jun 14, 2016
    @Ouyangan
    嗯,重点不是我如何再次获取 token ,而是重新获取到 token 后重复 token 过期前的那次网络操作。
    cxe2v
        3
    cxe2v  
       Jun 14, 2016
    生成 token 的时候把 token 的过期时间记下来,在过期时间后就再去获取新的 token
    fds
        4
    fds  
       Jun 14, 2016
    把操作记录下来呗……
    Totato5749
        5
    Totato5749  
    OP
       Jun 14, 2016
    @cxe2v
    问题在于有些 token 过期的原因并不是单纯的因为 token 到期,这样判断是不准确的
    eminemcola
        6
    eminemcola  
       Jun 14, 2016
    当返回 token 过期错误时,在 onError 中重新做获取 token 请求,再在获取成功的 callback 中重复用户过期前的操作。这中间的错误提示不显示给用户,对用户来说就是等得更久了点吧。应该可以避免察觉到你所说的断裂感?
    hsj1992
        7
    hsj1992  
       Jun 14, 2016
    @Totato5749
    @cxe2v 指的是对应 [用户只是单纯的在同一台设备上使用到 token 到期] 的情况,这应该是“ token 到期”的大头。
    撕裂感是因为“出错——>处理”产生的时间,那么,不能从源头“减少 token 到期错误”入手么?
    magicdawn
        8
    magicdawn  
       Jun 14, 2016
    @Ouyangan

    怎么帮登录? 存密码?
    Ouyangan
        9
    Ouyangan  
       Jun 14, 2016
    @magicdawn 用户登录的时候你把 usename,password 存储下来 ,token 无效的时候,自己帮用户提交一次登录,根据服务器返回的信息判断 token 是否有效,然后进行下一步操作.
    tinyproxy
        10
    tinyproxy  
       Jun 14, 2016 via iPhone
    1. 让服务器给 refresh token ,用来获取新的 token ,不然就让后端把 ttl 弄长一点。
    2. 你们啥业务这么容易登录过期啊,没啥要紧的东西后端调整 ttl 也就几分钟的事情,你们要业务非常重要,那你这种尝试自动提交账号密码登录简直就是作死。
    3. 说存账号密码的,从安全性来说这是个下策
    tinyproxy
        11
    tinyproxy  
       Jun 14, 2016 via iPhone
    至于你说的其他设备登录,当前设备 token 过期,也让后端把单点登录限制去了,不同意让产品跟他撕逼,你也用不着管,锅一下子就甩干净了
    ki41foo
        12
    ki41foo  
       Jun 14, 2016
    如果 token 只能通过登录获取的话,只能存帐号密码自动登录了啊。
    ifane
        13
    ifane  
       Jun 15, 2016
    我做模拟登录教务系统的时候,cookie 会过期,解决办法我就只能要做啥操作前,判断 cookie 有没有过期,如果过期了就只能重新模拟登录了
    dearmadman
        14
    dearmadman  
       Jun 15, 2016
    /**
    * 资源获取帮助类,需求:
    * 1. 常用请求方法
    * 2. 自动发送请求头
    * 3. 根据状态码进行刷新 token
    * 4. 刷新 token 后自动请求上次请求内容
    * 5. refresh token 过期时提示登录
    * 6. 请求方法返回: 状态码 无论 500 还是 0 都会返回 API 内容, token 过期刷新失败直接返回 false
    */
    import storage from './storage.js'
    import api from './api.js'

    var http = {
    $http: {},
    config ($http) {
    this.$http = $http
    },
    http (url, data, options, method) {
    return this.$http({url: url, method: method, data: data, options: this.autoHeaders(options)}).then((res) => {
    let body = res.data
    let status = body.status.code
    if (status === 401) {
    return this.refresh().then((res) => {
    if (res) return this.http(url, data, options, method)
    return false
    })
    }
    return body
    })
    },
    get (url, data, options) {
    return this.http(url, data, options, 'GET')
    },
    post (url, data, options) {
    return this.http(url, data, options, 'POST')
    },
    delete (url, data, options) {
    return this.http(url, data, options, 'DELETE')
    },
    put (url, data, options) {
    return this.http(url, data, options, 'PUT')
    },
    refresh () {
    this.$http.post(api.refresh, null, this.autoHeaders()).then((res) => {
    if (res.data.status.code === 0) {
    this.storage.setItem('token', res.data.data.token)
    return true
    }
    return false
    })
    },
    autoHeaders (options = {}) {
    return Object.assign({}, {
    headers: {
    Authorization: `Bearer ${storage.getItem('token')}`
    }
    }, options)
    }
    }

    export default http


    这么写可以吗? 有哪些糟点?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   6080 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 06:11 · PVG 14:11 · LAX 23:11 · JFK 02:11
    ♥ Do have faith in what you're doing.