In order for frontend apps to connect to LiveKit rooms, they need a token generated by your backend server. In this guide, we'll walk through how to set up a server to generate tokens for your frontend.
1. Install LiveKit Server SDK
go get github.com/livekit/server-sdk-go/v2
# yarn:yarn add livekit-server-sdk# npm:npm install livekit-server-sdk --save
# Add to your Gemfilegem 'livekit-server-sdk'
pip install livekit-api
# Cargo.toml[package]name = "example_server"version = "0.1.0"edition = "2021"[dependencies]livekit-api = "0.2.0"# Remaining deps are for the example serverwarp = "0.3"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1", features = ["full"] }
composer require agence104/livekit-server-sdk
2. Keys and Configuration
Create a new file at development.env
and with your API Key and Secret:
export LIVEKIT_API_KEY=<your API Key>export LIVEKIT_API_SECRET=<your API Secret>
3. Make an endpoint that returns a token
Create a server:
// server.goimport ("net/http""log""time""os""github.com/livekit/protocol/auth")func getJoinToken(room, identity string) string {at := auth.NewAccessToken(os.Getenv("LIVEKIT_API_KEY"), os.Getenv("LIVEKIT_API_SECRET"))grant := &auth.VideoGrant{RoomJoin: true,Room: room,}at.AddGrant(grant).SetIdentity(identity).SetValidFor(time.Hour)token, _ := at.ToJWT()return token}func main() {http.HandleFunc("/getToken", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte(getJoinToken("my-room", "identity")))})log.Fatal(http.ListenAndServe(":8080", nil))}
// server.jsimport express from 'express';import { AccessToken } from 'livekit-server-sdk';const createToken = async () => {// If this room doesn't exist, it'll be automatically created when the first// participant joinsconst roomName = 'quickstart-room';// Identifier to be used for participant.// It's available as LocalParticipant.identity with livekit-client SDKconst participantName = 'quickstart-username';const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {identity: participantName,// Token to expire after 10 minutesttl: '10m',});at.addGrant({ roomJoin: true, room: roomName });return await at.toJwt();};const app = express();const port = 3000;app.get('/getToken', async (req, res) => {res.send(await createToken());});app.listen(port, () => {console.log(`Server listening on port ${port}`);});
# server.rbrequire 'livekit'require 'sinatra'def createToken()token = LiveKit::AccessToken.new(api_key: ENV['LIVEKIT_API_KEY'], api_secret: ENV['LIVEKIT_API_SECRET'])token.identity = 'quickstart-identity'token.name = 'quickstart-name'token.add_grant(roomJoin: true, room: 'room-name')token.to_jwtendget '/getToken' docreateTokenend
# server.pyimport osfrom livekit import apifrom flask import Flaskapp = Flask(__name__)@app.route('/getToken')def getToken():token = api.AccessToken(os.getenv('LIVEKIT_API_KEY'), os.getenv('LIVEKIT_API_SECRET')) \.with_identity("identity") \.with_name("my name") \.with_grants(api.VideoGrants(room_join=True,room="my-room",))return token.to_jwt()
// src/main.rsuse livekit_api::access_token;use warp::Filter;use serde::{Serialize, Deserialize};use std::env;#[tokio::main]async fn main() {// Define the routelet create_token_route = warp::path("create-token").map(|| {let token = create_token().unwrap();warp::reply::json(&TokenResponse { token })});// Start the serverwarp::serve(create_token_route).run(([127, 0, 0, 1], 3030)).await;}// Token creation functionfn create_token() -> Result<String, access_token::AccessTokenError> {let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set");let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set");let token = access_token::AccessToken::with_api_key(&api_key, &api_secret).with_identity("identity").with_name("name").with_grants(access_token::VideoGrants {room_join: true,room: "my-room".to_string(),..Default::default()}).to_jwt();return token}// Response structure#[derive(Serialize, Deserialize)]struct TokenResponse {token: String,}
// If this room doesn't exist, it'll be automatically created when the first// participant joins.$roomName = 'name-of-room';// The identifier to be used for participant.$participantName = 'user-name';// Define the token options.$tokenOptions = (new AccessTokenOptions())->setIdentity($participantName);// Define the video grants.$videoGrant = (new VideoGrant())->setRoomJoin()->setRoomName($roomName);// Initialize and fetch the JWT Token.$token = (new AccessToken(getenv('LIVEKIT_API_KEY'), getenv('LIVEKIT_API_SECRET')))->init($tokenOptions)->setGrant($videoGrant)->toJwt();
Load the environment variables and run the server:
$ source development.env$ go run server.go
$ source development.env$ node server.js
$ source development.env$ ruby server.rb
$ source development.env$ python server.py
$ source development.env$ cargo r src/main.rs
$ source development.env$ php server.php
Note
See the Authentication page for more information on how to generate tokens with custom permissions.
4. Create a frontend app to connect
Create a frontend app that fetches a token from the server we just made, then uses it to connect to a LiveKit room: