用kotlin写一个token的生成和校验
能用代码说的话,我不喜欢用文字来过多的描述。所以我就直接上代码了。/** * 用于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 = { 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) 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有什么区别?
发行虚拟货币需要几步?现在发行虚拟货币真的很简单,杠精不要不经过调查就来杠!所有虚拟货币上主网都会开源自己的代码,只需要复制粘贴,熟练点的人十分钟就能搞一个虚拟货币。三步搞定第一,复制代码。第二,改名字
为什么坚定看好新能源基建?去年四季度以来,我对新能源赛道的关注点逐步从上游设备商组件商转移到新能源基建子赛道,核心逻辑在于市场竞争格局的快速变化,上游设备组件环节由于扩张壁垒不高导致产能快速膨胀,产能严重过
新能源的市场怎么样零跑C11放到同价位的燃油车中比较,也同样具有相当强的竞争力。就拿动力操控来说,售价19。98万的零跑C11性能版配备了400kW电机,峰值扭矩可以达到720Nm,4。8秒即可破百
终于等到腾讯今天腾讯的意外跳水大跌,坊间一片惊恐。但对于鸟哥来说,正是一个期待已久,终于发生的事件,淡定中略有喜悦。没有人知道腾讯为何突然跳水,有传言说有版号利空等等,最终都被否认。事实上,鸟
无人驾驶真的可行吗?汽车无人驾驶普及主要受到两个因素控制一个是技术成熟度的问题,一个是市场需求的问题。技术成熟度主要是人工智能,人工智能主要细分技术包括,计算机视觉与深度学习。同时以传感器以及高速芯片
iPhone14外观升级硬件更强价格很香,网友感慨这才是真旗舰在过去的两年里,苹果在手机市场上的表现非常出色。它不仅经常在中国的京东平台上赢得每月的销售冠军,而且还在全球市场上追逐三星。如果不考虑销售和利润,苹果显然已经成为手机市场上最亮的明
Golang入门到项目实战golang关键字continuecontinue只能用在循环中,在go中只能用在for循环中,它可以终止本次循环,进行下一次循环。在continue语句后添加标签时,表示开始标签对应的循环。go语言continu
2022买手机眼光要放长远,这三款旗舰机,用四五年轻而易举初春伊始,最近很多朋友打算购入新机,很多人来咨询小编有什么推荐?根据长期使用体验拉满的原则,以下三台旗舰机,虽然贵点,但真的值得入手。一加10Pro这款手机可以说是硬核玩家的梦中情
苹果在荷兰再被罚500万欧元金额累计达2500万欧元据国外媒体报道,荷兰反垄断监管机构周一再次对苹果开出500万欧元的罚单,苹果对于荷兰交友应用程序替代支付系统的解决方案依仍然不符合反垄断机构的要求,这已经是其对苹果发出的第五次同类
苹果为什么到现在,都没有采用曲面屏?保持辨识度很重要自从全面屏时代开启之后,手机在外形设计方面就有了更多的可能性。全面屏的概念,很多人说来自于三星,这是三星在这方面做到了都属于自己的特色,并且也将全面屏技术沿用到了很多其他手机厂商制
申通快递1元购备受争议深交所问询函直指其合理性财联社新消费日报(记者李丹昱)讯,申通快递在情人节当天发布员工持股计划后,市场反应强烈。由于员工购买的价格仅为1元股,且参加对象以管理人员为主,申通快递股价一路走低。2月22日午间