|
| 1 | +--- |
| 2 | +title: Integrating Telegram OAuth with Web3Auth for Authentication |
| 3 | +image: "guides/banners/telegram.png" |
| 4 | +description: Learn how to integrate Telegram OAuth with Web3auth |
| 5 | +type: guide |
| 6 | +tags: [github, oauth, authentication] |
| 7 | +date: March 8, 2024 |
| 8 | +author: Web3Auth Team |
| 9 | +order: 1 |
| 10 | +communityPortalTopicId: |
| 11 | +--- |
| 12 | + |
| 13 | +import SEO from "@site/src/components/SEO"; |
| 14 | + |
| 15 | +<SEO |
| 16 | + title="Integrating Telegram OAuth with Web3Auth for Authentication" |
| 17 | + description="Learn how to integrate Telegram OAuth with Web3auth." |
| 18 | + image="https://web3auth.io/docs/guides/banners/telegram.png" |
| 19 | + slug="/guides/telegram-oauth" |
| 20 | +/> |
| 21 | + |
| 22 | +This guide will cover the basics of how to integrate Web3Auth with Telegram OAuth for authentication. Web3Auth is employed to provide Ethereum private |
| 23 | +key access and public address and Telegram OAuth is used to authenticate users |
| 24 | + |
| 25 | +Full example: https://github.com/Web3Auth/web3auth-pnp-examples/tree/main/web3auth-byoa/telegram-oauth-connection |
| 26 | + |
| 27 | +We use two web3auth libraries in this project: `@web3auth/ethereum-provider` and `@web3auth/node-sdk`. Also we are usign a telegram libray |
| 28 | +`@telegram-auth/server`. |
| 29 | + |
| 30 | +To install them, run: `npm install @web3auth/ethereum-provider @web3auth/node-sdk @telegram-auth/server` |
| 31 | + |
| 32 | +## How it works? |
| 33 | + |
| 34 | +Telegram is usign a particular Oauth flow. To start it, we need to call the [Telegram Login Widget](https://core.telegram.org/widgets/login). This |
| 35 | +widget will open a new window to the user to login into Telegram. After the user logs in, Telegram will send a the user information to callback url, |
| 36 | +that we have to validate. After that we will send the user information to Web3Auth to get the Ethereum private key and public address. |
| 37 | + |
| 38 | +## Create a JWKS file |
| 39 | + |
| 40 | +A JWKS stands for JSON Web Key Set. It is a set of keys containing the public keys that should be used to verify any JSON Web Token (JWT) issued by |
| 41 | +the authorization server and signed using the RS256 signing algorithm. |
| 42 | + |
| 43 | +If you don't know how to create a JWKS, you can follow this |
| 44 | +[web3auth tutorial](https://web3auth.io/docs/auth-provider-setup/byo-jwt-providers#how-to-create-jwks). This file must be located on a public |
| 45 | +endpoint. To test the example, you will need to modify the file located in the root directory of the project. |
| 46 | + |
| 47 | +Both the private and the public keys, that you used to create the JWKS, must be in the server directory. In our project, they are called `private.pem` |
| 48 | +and `public.pem`. |
| 49 | + |
| 50 | +## Set up Custom JWT Verifier |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | +To create a custom verifier for your JWT Provider, you'll need the follow this steps: |
| 55 | + |
| 56 | +1. The verifier Identifier, which would be the name. This name should be used in your .ENV file as `WEB3AUTH_VERIFIER`. |
| 57 | + |
| 58 | +2. **JWT Verifier ID**: JWT Verifier ID is the unique identifier to publicly represent a user on a verifier. e.g: `sub`, `email`, or even a custom |
| 59 | + field of your JWT payload that is unique in your system for each user. In this case, we are using the `sub` field. |
| 60 | + |
| 61 | +3. **JWK Endpoint**: An endpoint containing the JWKS used to sign the JWT. In my example I'm using a static github url file. |
| 62 | + |
| 63 | +4. In the Select JWT Validation. You will add `iss` and `aud` fields (eplace both with your real Github Client ID.). |
| 64 | + - The `iss` field is the issuer of the JWT. In this case "https://telegram.com" |
| 65 | + |
| 66 | +## How to create a Bot in telegram |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | +- In the search box from the Telegram App, search for @BotFather. |
| 71 | +- Click on the BotFather and then click on the start button. |
| 72 | +- Click on the `/newbot` command. |
| 73 | +- Choose a name for your bot, description and an image. |
| 74 | +- Also you will need to add a Domain. This domain will be used to validate the callback url. As Telegram don't allow a callback to localhost, we are |
| 75 | + going to use `ngrok` to get a https address of our localhost app. (you can change this domain later with `/setDomain` command) |
| 76 | +- After creating the bot, you can use the command `/token` to get the token of your bot. You will need the name of the bot and the token in the .ENV |
| 77 | + file. |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | +## Running the example |
| 82 | + |
| 83 | +Run the application in 2 consoles: |
| 84 | + |
| 85 | +```bash |
| 86 | +ngrok http 5005 |
| 87 | +``` |
| 88 | + |
| 89 | +```bash |
| 90 | +npm start |
| 91 | +``` |
| 92 | + |
| 93 | +1. Add the URL from ngrok to the `.env` file as `SERVER_HOST_URL` and go to the Telegram Father Bot and send `/setdomain` and set the URL from ngrok |
| 94 | + from the your bot. |
| 95 | + |
| 96 | +2. Open your browser and navigate to `http://<URL>/telegram/login` to initiate the Telegram OAuth flow. |
| 97 | + |
| 98 | +3. Finally, after loginning in as a result, you will receive in the callback url a JSON with the user data, the JWT token, the Ethereum address and |
| 99 | + private key. |
| 100 | + |
| 101 | +```json |
| 102 | +{ |
| 103 | + "user": { |
| 104 | + "id": "<id>", |
| 105 | + "first_name": "<name>", |
| 106 | + "username": "<user>", |
| 107 | + "photo_url": "https://t.me/i/userpic/320/...lkx13ek4.jpg", |
| 108 | + "auth_date": "1710254881" |
| 109 | + }, |
| 110 | + "JWTtoken": "eyJhbGciO...7FhzkQOw", |
| 111 | + "ethData": { |
| 112 | + "ethPrivateKey": "a310362754543e....2d726ed6", |
| 113 | + "ethPublicAddress": ["0xaad13359bb....2930e962278c19"] |
| 114 | + } |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +## Code guide |
| 119 | + |
| 120 | +In the example, we are using express for the server. This are the Endpoint that we are using: |
| 121 | + |
| 122 | +- The initial endpoint to start the Telegram OAuth flow. Before we need to create the login.html file with the |
| 123 | + [Telegram Login Widget](https://core.telegram.org/widgets/login). |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | +```javascript |
| 128 | +app.get("/telegram/login", async (req, res) => { |
| 129 | + // load file, replace string and send it |
| 130 | + const file = path.join(__dirname, "login.html"); |
| 131 | + fs.readFile(file, "utf8", (err, data) => { |
| 132 | + if (err) { |
| 133 | + return console.log(err); |
| 134 | + } |
| 135 | + const result = data.replace(/{{TELEGRAM_BOT_NAME}}/g, TELEGRAM_BOT_NAME).replace(/{{TELEGRAM_BOT_CALLBACK}}/g, TELEGRAM_REDIRECT_URI); |
| 136 | + |
| 137 | + res.send(result); |
| 138 | + }); |
| 139 | +}); |
| 140 | +``` |
| 141 | + |
| 142 | +- The Callback endpoint validate de information and generate the private key with the JWT token. |
| 143 | + |
| 144 | +```javascript |
| 145 | +app.get("/telegram/callback", async (req, res) => { |
| 146 | + const token = TELEGRAM_BOT_TOKEN; |
| 147 | + const validator = new AuthDataValidator({ botToken: token }); |
| 148 | + const data = objectToAuthDataMap(req.query || {}); |
| 149 | + try { |
| 150 | + // validate the data |
| 151 | + const user = await validator.validate(data); |
| 152 | + const JWTtoken = generateJwtToken(user); |
| 153 | + // get the private key and address |
| 154 | + const ethData = await getPrivateKey(JWTtoken, user.id.toString()); |
| 155 | + res.json({ user, JWTtoken, ethData }); |
| 156 | + } catch (error) { |
| 157 | + console.error(error); |
| 158 | + } |
| 159 | +}); |
| 160 | +``` |
| 161 | + |
| 162 | +In the `getPrivateKey` function, we use Web3auth to establish a connection with the provider and get both the address and the private key. |
| 163 | + |
| 164 | +```javascript |
| 165 | +const getPrivateKey = async (idToken: string, verifierId: string) => { |
| 166 | + const web3authNodeprovider = await web3auth.connect({ |
| 167 | + verifier: process.env.WEB3AUTH_VERIFIER, |
| 168 | + verifierId, |
| 169 | + idToken, |
| 170 | + }); |
| 171 | + // The private key returned here is the CoreKit Key |
| 172 | + const ethPrivateKey = await web3authNodeprovider.request({ method: "eth_private_key" }); |
| 173 | + const ethPublicAddress = await web3authNodeprovider.request({ method: "eth_accounts" }); |
| 174 | + const ethData = { |
| 175 | + ethPrivateKey, |
| 176 | + ethPublicAddress, |
| 177 | + }; |
| 178 | + return ethData; |
| 179 | +}; |
| 180 | +``` |
| 181 | + |
| 182 | +References |
| 183 | + |
| 184 | +- [Custom JWT providers in Web3auth](https://web3auth.io/docs/auth-provider-setup/byo-jwt-providers) |
| 185 | +- [Telegram Login Widget](https://core.telegram.org/widgets/login) |
0 commit comments