Telegram第三方登录步骤
网上看到的不多,简单做个记录,本文主要对下面的文章做补充
整体步骤为:
- 找 botFather 创建机器人
- 给机器人设置域名白名单,用于设置回调地址,官方回把用户信息返回此处,所以注意,域名需要能被 tg 官方调用到,像内网、国内 ip 等,是无法回调成功的;而且需要配置 https
- 去官方的
https://core.telegram.org/widgets/login#widget-configuration
选择回调方式;回调方式有两种,第一种直接返回前端,第二种接口后端
以第一种为例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script async src="https://telegram.org/js/telegram-widget.js?22" data-telegram-login="watchx_test2_bot" data-size="large" data-onauth="onTelegramAuth(user)" data-request-access="write"></script> <script type="text/javascript"> function onTelegramAuth(user) { alert('Logged in as ' + user.first_name + ' ' + user.last_name + ' (' + user.id + (user.username ? ', @' + user.username : '') + ')'); } </script></body> </html>
由于官方源码 iframe 弹窗,所以需要把 script
标签放入 body
中
最后,前端把获取到的 name,last_name,等信息,全部传到后端,后端根据哈希做完整性校验,其中 botToken 就是前面拿到的 token
逻辑参考:
https://gist.github.com/MakStashkevich/7ae71729adbe3cbe2a662a7e16df6ea2
@Data public class OauthTgDto { /** tg id*/ String id; String firstName; String username; /** 推特头像*/ String photoUrl; /** 授权时间*/ String authDate; /** 验证哈希*/ String hash; } public static boolean checkTelegramAuthorization(OauthTgDto params, String botToken) throws NoSuchAlgorithmException, InvalidKeyException { // 构造数据字符串 String dataCheckString = getTokenStringBuilder(params); // 使用 bot token 计算密钥 MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] secretKey = digest.digest(botToken.getBytes(StandardCharsets.UTF_8)); // 使用密钥计算哈希 Mac sha256Hmac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "HmacSHA256"); sha256Hmac.init(secretKeySpec); byte[] computedHash = sha256Hmac.doFinal(dataCheckString.getBytes(StandardCharsets.UTF_8)); // 将计算出的哈希值转换为 Base64 编码 String computedHashString = bytesToHex(computedHash); // 比较计算的哈希和传递的哈希 return !computedHashString.equals(params.getHash()); } private static @NotNull String getTokenStringBuilder(OauthTgDto params) { Map<String, String> dataMap = new HashMap<>(); dataMap.put("auth_date", params.getAuthDate()); dataMap.put("first_name", params.getFirstName()); dataMap.put("id", params.getId()); dataMap.put("username", params.getUsername()); dataMap.put("photo_url", params.getPhotoUrl()); return dataMap.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(entry -> entry.getKey() + "=" + entry.getValue()) .collect(Collectors.joining("\n")); } private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }
这是一段防爬代码块,我不介意文章被爬取,但请注明出处 console.log("作者主页:https://www.cnblogs.com/Go-Solo"); console.log("原文地址:https://www.cnblogs.com/Go-Solo/p/18367728");
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库