該存儲庫提供了可與Cocoda映射工具一起使用的登錄服務器。它允許用戶使用不同的提供商(例如github,orcid)進行身份驗證。有關如何使用此情況的示例,請參見https://coli-conc.gbv.de/login/api。
.envproviders.jsonapplications.jsonLogin-Server需要Node.js(> = = V18,V20)並訪問MongoDB數據庫(> = V5,V7推薦)。
git clone https://github.com/gbv/login-server.git
cd login-server
npm install
# after setting up or changing providers, create indexes
npm run indexes也可以通過Docker獲得登錄服務器。請參閱https://github.com/gbv/login-server/blob/master/docker/dreadme.md上的文檔。
如果在反向代理後面運行服務器,請確保包括X-Forwarded-Proto標頭,允許所有HTTP方法,並啟用Websocket代理。
您需要提供兩個配置文件:
.env配置應用程序:
# recommended, port for express, default: 3004
PORT=
# recommended, full base URL, default: http://localhost[:PORT]/
# (required when used in production or behind a reverse proxy)
BASE_URL=
# title of application (will be shown in header)
TITLE=My Login Server
# list of allowed origins separated by comma, includes the hostname of BASE_URL by default
ALLOWED_ORIGINS=
# required for some strategies to enable production mode, default: development
NODE_ENV=production
# strongly recommended, imprint and privacy URLs for footer and clients
IMPRINT_URL=
PRIVACY_URL=
# recommended, secret used by the session
SESSION_SECRET=
# optional, maximum number of days a session is valid (rolling), default: 30
COOKIE_MAX_DAYS=
# threshold in minutes when to send "sessionAboutToExpire" events, default: 60
SESSION_EXPIRATION_MESSAGE_THRESHOLD=
# interval in minutes in which to check for expiring sessions, default: 5
SESSION_EXPIRATION_MESSAGE_INTERVAL=
# username used for MongoDB, default: <empty>
MONGO_USER=
# password used for MongoDB, default: <empty>
MONGO_PASS=
# host used for MongoDB, default: 127.0.0.1
MONGO_HOST=
# port used for MongoDB, default: 27017
MONGO_PORT=
# database used for MongoDB, default: login-server
MONGO_DB=
# the rate limit window in ms, default: 60 * 1000
RATE_LIMIT_WINDOW=
# the rate limit tries, default: 10
RATE_LIMIT_MAX=
# a jsonwebtoken compatible keypair
JWT_PRIVATE_KEY_PATH=
JWT_PUBLIC_KEY_PATH=
# the jsonwebtoken algorithm used
JWT_ALGORITHM=
# expiration time of JWTs in seconds, default: 120, min: 10
JWT_EXPIRES_IN=
# URL for Sources, default: https://github.com/gbv/login-server
SOURCES_URL=
# the path to the providers.json file, default: ./providers.json
PROVIDERS_PATH=
# log = log all messages, warn = only log warnings and errors, error = only log errorsl default: log
VERBOSITY=providers.json配置提供商。參見提供者。
applications.json為了向用戶提供有關哪些應用程序訪問其數據的信息,哪些應用程序啟動了會話的登錄名,您可以在applications.json中提供應用程序列表。該列表必須是一系列對象,每個對像都需要具有url和name 。例子:
[
{
"url" : " https://bartoc.org " ,
"name" : " BARTOC "
},
{
"url" : " https://coli-conc.gbv.de/coli-rich/ " ,
"name" : " coli-rich "
},
{
"url" : " https://coli-conc.gbv.de/cocoda/app/ " ,
"name" : " Cocoda "
},
{
"url" : " https://coli-conc.gbv.de/cocoda/dev/ " ,
"name" : " Cocoda (dev) "
},
{
"url" : " https://coli-conc.gbv.de/cocoda/rvk/ " ,
"name" : " Cocoda (RVK) "
},
{
"url" : " https://coli-conc.gbv.de/cocoda/wikidata/ " ,
"name" : " Cocoda (Wikidata) "
},
{
"url" : " https://coli-conc.gbv.de/cocoda/ " ,
"name" : " Cocoda (other) "
},
{
"url" : " https://coli-conc.gbv.de " ,
"name" : " Other coli-conc application "
}
]應該訪問URL,因為接口將鏈接到它。會話與應用程序的推薦子URL包含應用程序的url相關聯。應用程序將從上到底檢查,因此您應該從最具體的URL訂購至最少特定的URL(請參見上面的示例)。
npm run start該服務器提供Web接口,HTTP API和Websocket。
Web界面允許用戶創建和管理與身份提供商的多個身份的連接(請參閱提供商)的帳戶。提供商用於對用戶進行身份驗證,因為登錄服務器沒有存儲任何密碼(單登錄)。
HTTP API和Websocket允許客戶端應用程序與登錄服務器進行交互,例如,檢查用戶是否已登錄並找出屬於用戶的身份(請參閱JoavaScript庫,請參見login-client和login-client-vue,以使用login-server連接Web應用程序)。
登錄服務器可以進一步用於對用戶進行對其他服務的身份驗證,以便用戶可以證明其身份。
目錄bin包含用於管理服務器實例的輔助腳本,例如列出用戶帳戶和管理本地提供商。
測試使用與.env中配置的相同的mongoDB,僅在數據庫名稱之後的後綴-test中使用。
npm test Login-Server使用Passport(GitHub)作為身份驗證中間件。護照使用所謂的“策略”來支持不同提供商的身份驗證。可以在此處找到可用策略的列表。目前在登錄服務器中支持的策略是:
由於策略在其驗證回調中使用不同的參數,因此每個策略在文件夾strategies/中都有自己的包裝文件。要在登錄服務器中添加另一種策略,請添加一個名為{name}.js (其中{name}文件是與passport.authenticate一起使用的策略的名稱),其中包括以下結構(github作為例如):
/**
* OAuth Stategy for GitHub.
*/
// Import strategy here
import { Strategy } from "passport-github"
// Don't change this part!
export default ( options , provider , callback ) => new Strategy ( options ,
// Strategies have different callback parameters.
// `req` is always the first and the `done` callback is always last.
( req , token , tokenSecret , profile , done ) => {
// Prepare a standardized object for the user profile,
// usually using information from the `profile` parameter
let providerProfile = {
// Required, don't change this!
provider : provider . id ,
// Required: Choose a field that represents a unique user ID for this user
id : profile . id ,
// Optional: Provides a display name (e.g. full name)
name : profile . displayName ,
// Optional: Provides a username
username : profile . username
}
// Call a custom callback. `req`, `providerProfile`, and `done` are required,
// `token` and `tokenSecret` can be null.
callback ( req , token , tokenSecret , providerProfile , done )
} )您可以將現有策略視為示例,並通過拉動請求添加您自己的策略。
添加策略後,您可以通過將提供商添加到providers.json 。
[
{
"id" : " github " ,
"strategy" : " github " ,
"name" : " GitHub " ,
"template" : " https://github.com/{username} " ,
"options" : {
"clientID" : " abcdef1234567890 " ,
"clientSecret" : " abcdef1234567890abcdef1234567890 "
},
"image" : " https://upload.wikimedia.org/wikipedia/commons/9/91/Octicons-mark-github.svg " ,
"url" : " https://github.com "
}
]提供商列表中的每個對像都可以具有以下屬性:
id (必需) - 提供商的唯一ID。strategy (必需) - 提供商使用的護照策略的名稱。name (必需) - 提供商的名稱。template (可選) - 生成URI的模板字符串(佔位符{field}可以是providerProfile對像中提供的任何字段,通常是{id}或{username} )。credentialsNecessary (可選) - 如果該提供商需要用戶名和密碼憑據,則將其設置為true 。 Login-Server將不是重定向(對於OAuth),而是將顯示登錄表格,該表格將將憑據發送到端口端點。options (主要是必需的) - 該策略的選項對象,通常包含身份驗證端點的客戶端憑證。image (可選) - 與提供商關聯的圖像。將顯示在登錄頁面和連接的身份列表中。您可以在文件夾static/中提供靜態圖像。然後,該屬性的值將為static/myimage.svg 。如果文件名與提供商的id匹配,則圖像將自動關聯。url (可選) - 提供商的URL;將在其圖像 /圖標下/account上鍊接。策略github , orcid , mediawiki和stackexchange有默認URL。以下是一個示例providers.json顯示如何配置每個現有提供商:
[
{
"id" : " github " ,
"strategy" : " github " ,
"name" : " GitHub " ,
"template" : " https://github.com/{username} " ,
"options" : {
"clientID" : " abcdef1234567890 " ,
"clientSecret" : " abcdef1234567890abcdef1234567890 "
}
},
{
"id" : " orcid " ,
"strategy" : " orcid " ,
"name" : " ORCID " ,
"template" : " https://orcid.org/{id} " ,
"options" : {
"clientID" : " APP-abcdef1234567890 " ,
"clientSecret" : " abcdef1-23456-7890ab-cdef12-34567890 "
}
},
{
"id" : " mediawiki " ,
"strategy" : " mediawiki " ,
"name" : " Mediawiki " ,
"template" : " https://www.mediawiki.org/wiki/User:{username} " ,
"options" : {
"consumerKey" : " abcdef1234567890 " ,
"consumerSecret" : " abcdef1234567890abcdef1234567890 "
}
},
{
"id" : " stackexchange " ,
"strategy" : " stackexchange " ,
"name" : " Stack Exchange " ,
"template" : " https://stackexchange.com/users/{id} " ,
"options" : {
"clientID" : " 12345 " ,
"clientSecret" : " abcdef1234567890(( " ,
"stackAppsKey" : " 1234567890abcdefg(( "
}
},
{
"id" : " my-ldap " ,
"strategy" : " ldapauth " ,
"name" : " My LDAP " ,
"credentialsNecessary" : true ,
"options" : {
"server" : {
"url" : " ldap://ldap.example.com " ,
"bindDN" : " uid=admin,dc=example,dc=com " ,
"bindCredentials" : " abcdef1234567890 " ,
"searchBase" : " dc=example,dc=com " ,
"searchFilter" : " (uid={{username}}) "
}
}
},
{
"id" : " easydb " ,
"name" : " easydb test provider " ,
"strategy" : " easydb " ,
"credentialsNecessary" : true ,
"options" : {
"url" : " https://easydb5-test.example.com/api/v1/ "
}
},
{
"id" : " some-script " ,
"strategy" : " script " ,
"name" : " Some Script " ,
"credentialsNecessary" : true ,
"template" : " https://example.org/some-script/{id} " ,
"options" : {
"script" : " ./bin/example-script "
}
},
{
"id" : " cbs " ,
"strategy" : " cbs " ,
"name" : " CBS " ,
"credentialsNecessary" : true ,
"template" : " cbs:{id} " ,
"options" : {
"url" : " https://example.com/ext/api/colirich/users/info " ,
"apiKey" : " abcdef1234567890 "
}
}
]要配置本地提供商,請在bin/manage-local.js下使用提供的腳本。它將允許您創建/刪除本地提供商,並為本地提供商創建/刪除用戶。
您可以在.env中使用providers.json調整提供PROVIDERS_PATH的路徑。
有關使用MediaWiki提供商的註釋:
"baseURL": "https://www.wikidata.org/" 。https://coli-conc.gbv.de/login/login/wikidata/return以獲取我們的登錄名字實例)。有關使用腳本提供商的註釋:
lib/script-strategy.js )。options.script中提供)可以相對於登錄服務器的根文件夾,也可以是絕對路徑(建議用於Docker)。bin/example-script中找到。chmod +x )。id值。可選地,可以提供name ,並將用作顯示名稱。Login-Server提供JSON Web令牌,可用於針對其他服務(例如JSKOS-Server)進行身份驗證。 jsonwebtoken用於簽名令牌。
默認情況下,當應用程序首次啟動時(2048位,使用node-rsa),將生成一個新的RSA鍵盤。默認情況下,該生成的鍵盤將在./private.key和./public.key中可用。您可以將./public.key文件提供給需要驗證令牌的任何其他服務。或者,當前使用的公鑰在 /關於端點上提供。
您還可以通過在.env中設置JWT_PRIVATE_KEY_PATH和JWT_PUBLIC_KEY_PATH來提供密鑰文件的自定義路徑。如果找不到一個或兩個鍵,將生成鍵。默認情況下,使用RS256算法,但是可以通過設置JWT_ALGORITHM使用任何其他公共密鑰算法。
默認情況下,每個令牌有效期為120秒。您可以通過在.env中設置JWT_EXPIRES_IN來調整此問題。
通過 /令牌端點或使用Type token的Websocket請求將接收令牌。此外,在用戶登錄後,然後在最後一個令牌到期之前定期通過Websocket發送令牌。
示例如何驗證令牌:
import jwt from "jsonwebtoken"
// token, e.g. from user request
let token = "..."
// get public key from file or endpoint
let publicKey = "..."
jwt . verify ( token , publicKey , ( error , decoded ) => {
if ( error ) {
// handle error
// ...
} else {
let { user , iat , exp } = decoded
// user is the user object
// iat is the issued timestamp
// exp is the expiration timestamp
// ...
}
} )另外,您可以使用Passport-JWT(示例將如下)。
顯示一個登陸頁面,其中包含有關登錄服務器的一般信息。
顯示一個網站來管理一個人的用戶帳戶(如果已經進行了認證)或重定向到/login (如果未進行身份驗證)。
顯示一個網站,以管理用戶的會話(如果已進行身份驗證)或重定向到/login (如果未進行身份驗證)。
顯示一個網站登錄(如果未進行身份驗證)或直接到/account (如果已進行身份驗證)。
如果給出了查詢參數redirect_uri ,則該站點將在成功登錄後重定向到指定的URI。 (如果給出了參數但為空,則將使用轉介器作為URI。)
顯示提供商的登錄頁面。對於OAuth提供商,此頁面將重定向到提供商的頁面以連接您的身份,然後將其重定向到/login/:provider/return 。對於使用憑據的提供商,這將顯示登錄表格。
此頁面還處理redirect_uri (請參見上面的/login )。
使用憑據的提供商的端點。如果成功,它將重定向到/account ,否則它將返回/login/:provider 。
將提供商與用戶斷開連接,並將其重定向到/account 。
將用戶從其帳戶中記錄下來。請注意,由於將其用於Websocket,因此將其保留。這使應用程序可以將事件發送到當前會話的活動Websocket,即使用戶已登錄。
顯示一個網站以刪除一個人的用戶帳戶。
將用戶帳戶刪除並重定向到/login 。
該服務器為每個OAuth提供商提供了OAuth重定向端點(重定向URI)。
OAuth請求的回調端點。將將所連接的身份保存到用戶(或者必要時創建新用戶),然後將其重定向到/account 。
在直接針對HTTP API和WebSocket API進行編程之前,請查看登錄 - 委託JavaScript瀏覽器庫。可以在此處看到它(該站點的來源)。
返回帶有鍵title (登錄服務器實例的標題), env (如development或production環境), publicKey (通常是RSA公共密鑰)和algorithm (使用的JSONWEBTOKEN算法)的對象。簽署JWT時,使用給定公共密鑰的相應私鑰。
返回可用提供商的列表(刪除敏感信息)。
返回當前登錄的用戶。沒有登錄用戶時返回404錯誤。
返回特定用戶。目前僅限於自己的用戶ID。
調整特定用戶。僅噹噹前登錄同一用戶時才能使用。允許屬性更改: name (其他所有內容都將被忽略)。
除當前會話外,除了當前用戶外,還要刪除當前用戶的所有會話。
使用SessionID :id刪除會話(需要是當前用戶的會話)。
以格式返回JSON Web令牌:
{
"token" : " <JWT> " ,
"expiresIn" : 120
}另請參閱:JWTS。
令牌本身將包含一個user屬性(該屬性包含有關當前登錄的用戶的信息,或者如果未登錄用戶,則為null)和在WebSocket連接中進行身份驗證所需的sessionID屬性。
基本URL /發送有關當前用戶或會話的事件的WebSocket API。事件以JSON編碼的字符串發送,看起來像這樣:
{
"type" : " event name (see below) " ,
"date" : " date (as ISOString) " ,
"data" : {
"user" : {
"uri" : " URI of user " ,
"name" : " name of user " ,
"identities" : {
"xzy" : {
"id" : " ID of user for provider xzy " ,
"uri" : " URI or profile URL of user for provider xzy " ,
"name" : " display name of user for provider xzy (if available) " ,
"username" : " username of user for provider xzy (if available) "
}
}
}
}
}open - 在建立WebSocket連接後發送,使用此而不是ws.onopen !loggedIn用戶登錄時發送(如果用戶已經登錄,將在建立Websocket後立即發送)loggedOut - 在用戶登錄時發送(如果未登錄用戶,將在建立Websocket後立即發送)updated - 在更新用戶時發送(例如,添加了新的身份等)providers - 建立WebSocket連接後發送(由屬性data.providers組成。about在建立WebSocket連接後發送(屬性data將與get /aid中的格式相同)token - 當用戶登錄時發送,然後在以前的令牌到期之前以間隔(屬性data格式與get /token中的格式)進行登錄時發送)authenticated - 在請求身份驗證時作為成功答復發送(請參閱下文)pong作為ping類型請求的答案發送(可用於確定Websocket是否已建立)sessionAboutToExpire噹噹前關聯的會話即將到期時發送error - 通過Websocket作為對畸形消息的答案發送(由屬性data.message組成。帶有錯誤消息的消息)您也可以將請求發送到Websocket。這些也必須是以下形式編碼的JSON編碼的字符串:
{
"type" : " name of request "
}這是一個特殊請求,使用從get /令牌獲得的JWT將當前Websocket與特定會話相關聯(已發送請求對象需要屬性token )
當與登錄服務器不同的域使用Websocket時,有時需要authenticate請求。在這種情況下,需要通過API請求令牌(例如,使用選項credentials: "include"或axios withCredentials: true ),並通過Websocket發送。令牌包括加密的sessionID,然後將與WebSocket連接關聯。這是一個有關Web應用程序的工作流程的示例:https://coli-conc.gbv.de/login/api
以下是有關如何連接到Websocket的一個簡單示例。
// Assumes server is run on localhost:3005
let socket = new WebSocket ( "ws://localhost:3005" )
socket . addEventListener ( "message" , ( message ) => {
try {
let event = JSON . parse ( message )
alert ( event . event , event . user && event . user . uri )
} catch ( error ) {
console . warn ( "Error parsing WebSocket message" , message )
}
} ) 公關接受。
dev分支為基礎。 dev的更改將僅用於新版本的master 。僅適用於維護者
在開發過程中,請在dev部門上工作(或者更好,在功能分支中開發,並在準備就緒時合併成dev )。
當準備就緒新版本時(即功能完成,合併到dev ,所有測試成功)時,請運行隨附的發行腳本(如有必要,用“次要”或“ MARIAD”替換):
npm run release:patch這將:
dev上dev是最新的npm version patch (或“次要”/“ Major”)devmasterdev合併變化masterdev運行此操作後,GitHub操作將自動創建新的GitHub發行草稿。請手動編輯並發布該版本。
MIT©2019 Verbundzentrale des GBV(VZG)