能用代码说的话,我不喜欢用文字来过多的描述。所以我就直接上代码了。
/** * 用于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有什么区别?
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除