iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0

SSO 登入還沒搞定不過先來嘗試當初選擇 Rocket.chat 的另一個理由,將 Rocket.chat 嵌入我們的主應用的功能。

嵌入的方式是用 iframe 來達成,首先來設定。

在 Administration → Workspace → Settings → Accounts → Iframe ,先 Enabled。

然後 Iframe URL 填準備嵌入的 Nextjs 應用網址,例:http://localhost:3000

API URL 的部分需要說明一下 Rocket.chat iframe 的認證方式,Rocket.chat 會在 iframe 載入時呼叫 API URL 確認用戶是否已登入,這部分需要在 Nextjs 這端實作。

為求快速驗證功能先做一個陽春的 sso API,直接跟 Rocket.chat 取得 token 後回傳。

// src/app/api/sso/route.ts
import axios from "axios";

export async function POST(request: Request) {
  try {
    const res = await axios.post("http://localhost:3001/api/v1/login", {
      username: 'admin-user',
      password: 'admin-user-password',
    });
    if (res.data.status === "success") {
      return Response.json({
        loginToken: res.data.data.authToken,
      });
    }
  } catch (error) {
    return Response.json({
      status: 401,
    });
  }
}

先直接用創建 Workspace 時建立的 admin 帳號密碼經由 API 登入 Rocket.chat 取得 token 並回傳。

另外為了讓 iframe 請求 sso API 時不會被 CORS 擋住,要設定一下 Nextjs config。

// next.config.js

...

const config = {
  ...
  async headers() {
    return [
      {
        // matching all API routes
        source: "/api/:path*",
        headers: [
          { key: "Access-Control-Allow-Credentials", value: "true" },
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // replace this your actual Rocket.chat origin
          }, 
          {
            key: "Access-Control-Allow-Methods",
            value: "GET,DELETE,PATCH,POST,PUT",
          },
          {
            key: "Access-Control-Allow-Headers",
            value:
              "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
          },
        ],
      },
    ];
  },
};

...

然後回頭設定 Rocket.chat 的 Iframe API URL

http://localhost:3000/api/sso

這邊 sso API 寫的比較簡略,只是直接登入,不過如果用戶在 Rocket.chat 不存在也能先建立帳號後取得 token,可以看看官方的範例

另外先關掉 Administration → Settings → General 裡的 Restrict access inside any Iframe 選項好方便 localhost 連線,正式的時候要記得開回來。

然後就能在 Nextjs 開個 iframe 來看看效果,開一個新的 chat 頁面。

// src/app/[locale]/chat/page.tsx
"use client";

const Page = () => {
  return (
    <>
      <h1>{"Chat"}</h1>
      <iframe
        src="http://localhost:3001/channel/general/?layout=embedded"
        title="chat"
        width={400}
        height={600}
      ></iframe>
    </>
  );
};

export default Page;

iframe src 的格式如下:

{rocket_chat_url}/channel/{channel_name}/?layout=embedded

layout=embedded 會讓 Rocket.chat 以單一 channel 的模式呈現。

呈現的畫面會像這樣

https://res.cloudinary.com/dhcsjvhjg/image/upload/v1728482604/Screenshot_2024-10-09_at_10.02.47_PM_kanyo3.png

第一步遷入的效果看來是成功了,不過課題還很多,像是用戶驗證,樣式調整,還有選擇聊天室的介面等等。


上一篇
使用 Keycloak 登入 Rocket.chat
下一篇
Rocket.chat 客製化選項
系列文
Awesome self hosted 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言