Säkrare 2FA med RCS: Så lyfter Verified Sender och smarta knappar dina engångskoder

exempel för RCS OTP

Tvåfaktorsautentisering (2FA) och engångskoder (OTP) är grundstenar i modern digital säkerhet. Ändå förlitar sig de flesta företag fortfarande på traditionella textmeddelanden, en kanal som i allt högre grad plågas av ”smishing” (SMS-bedrägerier), spoofade avsändarnamn och onödig friktion för användaren.

När mobilkommunikationen nu moderniseras med RCS (Rich Communication Services) får autentiseringsflöden ett välbehövligt lyft. Genom att kombinera kryptografiskt säkrad avsändaridentitet med interaktiva åtgärder och operativsystemens inbyggda autofill-stöd, kan du erbjuda en inloggningsupplevelse som är både säkrare och snabbare.

Slut på smishing med Verified Sender ID

I traditionella textflöden är det alfanumeriska avsändarnamnet oskyddat mot manipulation. Bedragare kan sätta avsändaren till samma namn som din bank eller tjänst för att lura kunden.

RCS eliminerar detta problem genom Verified Sender ID:

  • Officiell varumärkesprofil: Koden levereras i en konversation märkt med företagets verifierade namn, logotyp och en operativsystemstyrd verifieringsbock.
  • Central validering: Profilen och nätverkstrafiken signeras och godkänns centralt av teleoperatörerna och plattformsägarna (Google och Apple). Det går inte att spoofa en verifierad RCS-avsändare.
  • Trygghet för slutanvändaren: Mottagaren behöver aldrig tveka på om koden faktiskt kommer från rätt källa.

När kunden ser er logotyp och verifieringsbocken vet de med 100 % säkerhet att koden är äkta.

Hur kodhantering och kopiering faktiskt fungerar i mobilen

För att förstå hur vi bygger bästa möjliga UX för OTP via RCS måste vi skilja på vad som sköts av operativsystemet och vad som styrs av RCS-knappar.

Operativsystemets inbyggda autofill och "Kopiera kod"

Det finns ingen specifik knapp i RCS-standarden för att kopiera text till urklipp. Istället hanteras detta av klientens och operativsystemets lokala intelligens (i både Android och iOS):

  • När meddelandet formateras enligt vedertagna mönster (t.ex. tydlig separation av siffror, ord som ”kod” eller ”verifieringskod”, eller domänbindning) känner telefonen automatiskt av koden.

  • Operativsystemet genererar då själv en ”Kopiera kod”-knapp i notifieringsbannern eller erbjuder att klistra in den direkt via tangentbordets autofill-rad i appen eller webbläsaren.

Nästa steg med RCS: 1-klicks direktverifiering

Där traditionella meddelanden stannar vid manuell kodinmatning, tillåter RCS Suggested Actions som tar användaren ett steg längre. Genom att skicka med en openUrlAction kan du erbjuda en knapp för direktverifiering:

  • Knappen öppnar en krypterad engångslänk (eller en app-djuplänk / Universal Link) som automatiskt validerar sessionen.

  • Kunden behöver varken memorera, kopiera eller knappa in någonting – ett klick på knappen slutför inloggningen.

Teknisk implementation: Kodgenerering, payload och validering

Ett komplett RCS OTP-flöde består av tre komponenter:

  1. Skapa en säker engångskod i backend.

  2. Skicka meddelandet via RCS API:et med strukturerad text (för OS-autofill) och en direktverifieringsknapp (samt definierad SMS-fallback).

  3. Ta emot och validera koden eller verifieringstoken.

Steg 1 & 2: Kodgenerering och utskick (Node.js)

I payloaden skickar vi koden tydligt formaterad i meddelandekroppen så att telefonens operativsystem kan erbjuda autofill/kopiering. Parallellt bifogar vi en action med openUrlAction som ger användaren valet att verifiera med ett klick.

📄
RCS OTP (Node.js)
Kopiera
const crypto = require('crypto');

// 1. Generera en kryptografiskt säker 6-siffrig kod och en engångstoken
function generateOTP() {
    return crypto.randomInt(100000, 999999).toString();
}

const otpCode = generateOTP();
const verifyToken = crypto.randomBytes(16).toString('hex');
const userPhone = "46700123456";
const apiKey = "DIN_API_NYCKEL";

// Spara koden och token i databas/cache med kort giltighetstid (t.ex. 3 minuter)
// await redis.setEx(`otp:${userPhone}`, 180, JSON.stringify({ code: otpCode, token: verifyToken }));

// 2. Bygg RCS-payloaden
const payload = {
    brand: "Min-Tjanst",
    agent: "Sakerhet",
    recipient: userPhone,
    // Fallback: OTP är tidskritiskt – sätt en låg timeout (30-45 sekunder)
    fallbackPolicy: "FallbackOnNoCapability,FallbackOnFailure,FallbackAfterTimeout",
    fallbackMessage: `Din verifieringskod för Min-Tjanst är: ${otpCode}`,
    fallbackTimeOutSeconds: 30,
    type: "Text",
    // Tydlig formatering underlättar operativsystemets inbyggda kod-detektering
    content: `Din verifieringskod är ${otpCode}. Koden är giltig i 3 minuter. Dela den aldrig med någon.`,
    suggestions: [
        {
            text: "Verifiera direkt",
            type: "OpenUrlAction",    
            url: `https://auth.mintjanst.se/verify?token=${verifyToken}`, // Djuplänk eller webblänk som validerar sessionen direkt
            postbackData: "action_verify_click",
        }
    ]
};

// 3. Skicka anropet till API:et
async function sendRcsOtp() {
    const response = await fetch("https://api.ip1.net/v3/conversations", {
        method: "POST",
        headers: {
            "Authorization": `Bearer ${apiKey}`,
            "Content-Type": "application/json"
        },
        body: JSON.stringify(payload)
    });

    console.log("OTP skickat. Status:", response.status);
}

sendRcsOtp();

Steg 3: Validering i backend

Backend-systemet behöver kunna hantera valideringen på två sätt: antingen via den manuellt inmatade/inklistrade koden, eller via direktlänken.

📄
Validate RCS OTP (Node.js)
Kopiera
// Exempel i Express.js för manuell inmatning
app.post('/api/verify-code', async (req, res) => {
    const { phone, code } = req.body;
    
    // Hämta lagrad session
    // const sessionData = JSON.parse(await redis.get(`otp:${phone}`));

    if (!sessionData) {
        return res.status(400).json({ error: "Koden har löpt ut eller existerar inte." });
    }

    if (sessionData.code === code) {
        // Förbruka koden omedelbart efter godkänd validering
        // await redis.del(`otp:${phone}`);
        return res.status(200).json({ success: true, message: "Verifiering lyckades." });
    }

    return res.status(401).json({ error: "Felaktig kod. Försök igen." });
});

// Exempel för 1-klicks direktverifiering via webb/djuplänk
app.get('/verify', async (req, res) => {
    const { token } = req.query;

    // Hitta session baserat på engångstoken
    // const user = await findUserByToken(token);

    if (!user) {
        return res.status(400).send("Länken är ogiltig eller har löpt ut.");
    }

    // Godkänn inloggningen och omdirigera användaren
    return res.redirect("https://mintjanst.se/dashboard?auth=success");
});

Best practices för RCS OTP och 2FA

  • Håll fallback-timeouten kort: Medan marknadsföring kan vänta flera minuter på RCS-leverans, sitter en användare som väntar på en OTP aktivt framför en inloggningsskärm. Sätt FallbackTimeOutSeconds till 30 – 45 sekunder så att ett SMS snabbt skickas om datatäckning saknas.

  • Separera koden visuellt i texten: Undvik att baka in siffrorna i långa meningar utan mellanrum. Att placera koden tydligt i texten hjälper både telefonben autofill-motorer och gör det lättare att läsa om kunden föredrar att memorera den.

  • Tydliga instruktioner i fallback: Om meddelandet faller tillbaka på SMS försvinner action-knappen. Se därför till att fallbackMessage innehåller den rena koden så att användaren enkelt kan slutföra processen oavsett kanal.
Dela artikeln