用kotlin写一个token的生成和校验

发布一下 0 0

能用代码说的话,我不喜欢用文字来过多的描述。所以我就直接上代码了。

/** * 用于token的生成和校验 */object HyAuth {    /**     * 过期     */    const val statusTimeOut = 0    /**     * 错误的token     */    const val statusWrong = 1    /**     * 状态正常     */    const val statusOk = 2    /**     * 域名      */    var domain: String = "jiaohongyun.cn"    /**     * 作者      */    var author: String = "hyjiao"    /**     * 应用名      */    var app: String = "Myapp"    /**     * 密钥      */    var security: String = "ssas1919119ssas"    /**     * 过期时间(7天)      */    var validityInMs = 3600 * 1000 * 24 * 7    fun initAuth(config: HyAuth.() -> Unit) {        this.config()    }    fun createToken(id: String, inData: () -> MutableMap<String, String> = { mutableMapOf() }): String {        val now = System.currentTimeMillis()        val header = HyHeader(domain, author, app)        val payload = HyPayload(id, inData())        val footer = HyFooter(security + now)        payload.customItems["creatAt"] = now.toString()        payload.customItems["expiresAt"] = (now + validityInMs).toString()        val gson = gson()        val str1 = EncryptUtil.en4Base64(gson.toJson(header))        val str2 = EncryptUtil.en4Base64(gson.toJson(payload))        val str3 = EncryptUtil.md5(str1) + EncryptUtil.md5(str2) + EncryptUtil.sha256(gson.toJson(footer))        return "$str1.$str2.$str3"    }    /**     * 返回状态     */    fun auth(token: String): Int {        val strs = token.split(""".""")        if (strs.size != 3) {            ////token 被篡改            return statusWrong        } else {            val str1 = EncryptUtil.de4Base64(strs[0])            val str2 = EncryptUtil.de4Base64(strs[1])            val str3 = strs[2]            val gson = gson()            val header = gson.fromJson(str1, HyHeader::class.javaObjectType)            val payload = gson.fromJson(str2, HyPayload::class.javaObjectType)            val footer = HyFooter(security + payload.customItems["creatAt"])            val str4 = EncryptUtil.md5(strs[0]) + EncryptUtil.md5(strs[1]) + EncryptUtil.sha256(gson.toJson(footer))            val now = System.currentTimeMillis()            val expiresAt = payload.customItems["expiresAt"]?.toLong()            when {                expiresAt == null -> {                    //无效的token,可能被篡改                    return statusWrong                }                now > expiresAt -> {                    //token 失效                    return statusTimeOut                }                header.app != app || header.author != author || header.domain != domain -> {                    //无效的token,可能被篡改                    return statusWrong                }                str3 != str4 -> {                    //无效的token,可能被篡改                    return statusWrong                }                else -> {                    return statusOk                }            }        }    }    /**     * 获取用户数据     */    fun getPayload(token: String): HyPayload? {        var payload: HyPayload? = null        val strs = token.split(""".""")        if (strs.size == 3) {            val str2 = EncryptUtil.de4Base64(strs[1])            val gson = Gson()            payload = gson.fromJson(str2, HyPayload::class.javaObjectType)        }        return payload    }    /**     * 获取用户ID     */    fun getUserId(token: String): Int? {        var result: Int? = null        val payload = getPayload(token)        payload?.let {            result = it.customItems[HyConstant.userId]?.toInt()        }        return result    }}private data class HyHeader(val domain: String, val author: String, val app: String)data class HyPayload(val id: String, val customItems: MutableMap<String, String>)private data class HyFooter(val security: String)/** * 这里只是测试代码  */fun main() {   HyAuth.initAuth {        this.app = "123456"        this.author = "123456"        this.security = "12safe5224asdfe"    }    val token = HyAuth.createToken("userId01")    HyAuth.auth(token) { status,payload ->        when (status) {            HyAuth.statusOk -> {                println("statusOk,用户:${payload?.id}")                println(token)            }            HyAuth.statusWrong -> {                println("statusWrong")                println(token)            }            HyAuth.statusTimeOut -> {                println("statusTimeOut")                println(token)            }        }    }    val userId = HyAuth.getUserId(token)    println(userId)}

再附上一个加密的工具

object EncryptUtil {    /**     * Base64加密     */    fun en4Base64(str:String):String{        return Base64.getEncoder().encodeToString(str.toByteArray())    }    /**     * Base64解密     */    fun de4Base64(str:String):String{        return Base64.getDecoder().decode(str).toString(Charsets.UTF_8)    }    /**     * AES加密     */    fun en4AES(str: String,pwd:String):String{        //参考 java 文档 Cipher        //1 、创建 cipher 对象        val cipher = Cipher.getInstance("AES")        //解密解密的 key        val keySpec = DESKeySpec(pwd.toByteArray())  //里面指定自己的密码        val kf  = SecretKeyFactory.getInstance("AES")  //DES 的密钥工厂        val key: Key? = kf.generateSecret(keySpec)     //通过密码创建 key        //2 初始化,指定加密或者解密模式,key        cipher.init(Cipher.ENCRYPT_MODE,key)        //3 加密和解密        val encrypt = cipher.doFinal(str.toByteArray())        return Base64.getEncoder().encodeToString(encrypt)    }    /**     * AES解密     */    fun de4AES(str: String,pwd:String):String{        //参考 java 文档 Cipher        //1 、创建 cipher 对象        val cipher = Cipher.getInstance("AES")        //解密解密的 key        val keySpec = DESKeySpec(pwd.toByteArray())  //里面指定自己的密码        val kf  = SecretKeyFactory.getInstance("AES")  //AES 的密钥工厂        val key: Key? = kf.generateSecret(keySpec)     //通过密码创建 key        //2 初始化,指定加密或者解密模式,key        cipher.init(Cipher.DECRYPT_MODE,key)        //3 加密和解密        //Base64 解码        val encrypt = cipher.doFinal(Base64.getDecoder().decode(str))        return encrypt.toString(Charsets.UTF_8)    }    /**     * des 加密     */    fun en4DES(str:String,pwd:String): String {        //参考 java 文档 Cipher        //1 、创建 cipher 对象        val cipher = Cipher.getInstance("DES")        //解密解密的 key        val keySpec = DESKeySpec(pwd.toByteArray())  //里面指定自己的密码        val kf  = SecretKeyFactory.getInstance("DES")  //DES 的密钥工厂        val key:Key? = kf.generateSecret(keySpec)     //通过密码创建 key        //2 初始化,指定加密或者解密模式,key        cipher.init(Cipher.ENCRYPT_MODE,key)        //3 加密和解密        val encrypt = cipher.doFinal(str.toByteArray())        return Base64.getEncoder().encodeToString(encrypt)    }    /**     * des 解密     */    fun de4DES(str:String,pwd:String): String{        //参考 java 文档 Cipher        //1 、创建 cipher 对象        val cipher = Cipher.getInstance("DES")        //解密解密的 key        val keySpec = DESKeySpec(pwd.toByteArray())  //里面指定自己的密码        val kf  = SecretKeyFactory.getInstance("DES")  //DES 的密钥工厂        val key:Key? = kf.generateSecret(keySpec)     //通过密码创建 key        //2 初始化,指定加密或者解密模式,key        cipher.init(Cipher.DECRYPT_MODE,key)        //3 加密和解密        //Base64 解码        val encrypt = cipher.doFinal(Base64.getDecoder().decode(str))        return encrypt.toString(Charsets.UTF_8)    }    /**     * md5加密     */    fun md5(input:String ): String {        val instance = MessageDigest.getInstance("MD5")        return toHex(instance, input)    }    /**     * sh256加密     */    fun sha256(input:String): String {        val instance = MessageDigest.getInstance("SHA-256")        return toHex(instance, input)    }    private fun toHex(instance: MessageDigest, input: String): String {        val result = instance.digest(input.toByteArray())        val stringBuilder = StringBuilder()        //转成 16 进制        result.forEach {            val value = it            //移位操作            val hex = value.toInt() and (0xFF)            val hexStr = Integer.toHexString(hex)            //如果是一位,则前面加0            if (hexStr.length == 1) {                stringBuilder.append("0").append(hexStr)            } else {                stringBuilder.append(hexStr)            }        }        return stringBuilder.toString()    }}

啰嗦几句:token是不需要保存在服务器端的,服务器端只负责生成、校验和读取token里保存的数据,比如userId。想在服务端保存token?如果在服务端保存了,那它和使用session有什么区别?

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/60299.html