이 저장소는 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 indexesLogin-Server는 Docker를 통해도 제공됩니다. 자세한 내용은 https://github.com/gbv/login-sererver/blob/master/docker/readme.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서버는 웹 인터페이스, HTTP API 및 WebSocket을 제공합니다.
웹 인터페이스를 통해 사용자는 ID 제공 업체의 여러 ID에 연결하여 계정을 생성하고 관리 할 수 있습니다 (제공자 참조). 로그인 서버가 암호 (단일 로그온)를 저장하지 않기 때문에 제공자는 사용자를 인증하는 데 사용됩니다.
HTTP API 및 WebSocket을 사용하면 클라이언트 애플리케이션이 로그인 서버와 상호 작용할 수 있습니다. 예를 들어 사용자가 로그인되었는지 확인하고 사용자가 속하는 ID를 찾을 수 있습니다 (로그인 서버와 웹 애플리케이션을 연결하기 위해 JavaScript 라이브러리의 로그인 클라이언트 및 로그인 클라이언트 및 로그인 클라이언트 vue 참조).
로그인 서버를 추가로 사용하여 다른 서비스에 대해 사용자를 인증하여 사용자가 신원을 증명할 수 있습니다.
디렉토리 bin 에는 사용자 계정 목록 및 로컬 제공 업체 관리와 같은 서버 인스턴스를 관리하기위한 도우미 스크립트가 포함되어 있습니다.
테스트는 데이터베이스 이름 뒤에 postfix -test 와 함께 .env 에서 구성된 것과 동일한 mongoDB를 사용합니다.
npm test Login-Server는 여권 (Github)을 인증 미들웨어로 사용합니다. 여권은 소위 "전략"을 사용하여 다른 공급자와의 인증을 지원합니다. 사용 가능한 전략 목록은 여기에서 찾을 수 있습니다. 로그인-서버에서 현재 지원되는 전략은 다음과 같습니다.
전략은 콜백 확인에 다른 매개 변수를 사용하기 때문에 각 전략에는 폴더 strategies/ 에 고유 한 래퍼 파일이 있습니다. 로그인-서버에 다른 전략을 추가하려면 {name}.js 라는 파일을 추가하십시오 (여기서 {name} passport.authenticate 과 함께 사용되는 전략의 이름입니다.
/**
* 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 에게 제공자를 추가하여 사용할 수 있습니다 .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 로 설정하십시오. 로그인-서버는 리디렉션 (OAUTH) 대신 자격 증명을 포스트 엔드 포인트로 보내는 로그인 양식을 표시합니다.options (주로 필수) - 전략의 옵션 개체로, 종종 인증 엔드 포인트에 대한 클라이언트 자격 증명이 포함됩니다.image (선택 사항) - 제공자와 관련된 이미지. 로그인 페이지 및 연결된 ID 목록에 표시됩니다. 폴더 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_PATH 를 사용하여 providers.json 파일의 경로를 조정할 수 있습니다.
MediaWiki 제공 업체 사용에 대한 메모 :
"baseURL": "https://www.wikidata.org/" 와 같은 옵션에서 해당 인스턴스에 대한 BaseUrl을 제공해야합니다.https://coli-conc.gbv.de/login/login/wikidata/return ).스크립트 제공 업체 사용에 대한 메모 :
lib/script-strategy.js 참조).options.script 에서 제공)는 Login Server의 루트 폴더와 관련이 있거나 절대 경로 (Docker에 권장) 일 수 있습니다.bin/example-script 에서 찾을 수 있습니다.chmod +x )이어야합니다.id 값이 설정된 유효한 JSON을 반환해야합니다. 선택적으로 name 제공 할 수 있으며 디스플레이 이름으로 사용됩니다.Login-Server는 JSON 웹 토큰 (JSKOS-Server와 같은 다른 서비스)에 대해 인증하는 데 사용할 수있는 JSON 웹 토큰을 제공합니다. JSONWEBTOKE는 토큰에 서명하는 데 사용됩니다.
기본적으로 응용 프로그램이 처음 시작될 때 (Node-RSA를 사용하여 2048 비트) 새로운 RSA KeyPair가 생성됩니다. 이 생성 된 KeyPair는 기본적으로 ./private.key 및 ./public.key 에서 사용할 수 있습니다. 토큰을 확인하는 데 필요한 다른 서비스에 ./public.key 파일을 제공 할 수 있습니다. 또는 현재 사용되는 공개 키는 /About Endpoint에서 제공됩니다.
JWT_PRIVATE_KEY_PATH 및 JWT_PUBLIC_KEY_PATH .env 로 설정하여 키 파일에 대한 사용자 정의 경로를 제공 할 수도 있습니다. 키 중 하나 또는 둘 다를 찾을 수 없으면 키가 생성됩니다. 기본적으로 RS256 알고리즘이 사용되지만 JWT_ALGORITHM 설정하여 다른 공개 키 알고리즘을 사용할 수 있습니다.
기본적으로 각 토큰은 120 초 동안 유효합니다. .env 에서 JWT_EXPIRES_IN 설정하여이를 조정할 수 있습니다.
토큰은 /토큰 엔드 포인트를 통해 또는 유형 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 으로 리디렉션합니다.
사용자를 계정에서 로그인합니다. 세션은 Websockets에 사용되기 때문에 유지됩니다. 이를 통해 응용 프로그램은 사용자가 로그 아웃 한 경우에도 현재 세션의 활성 Websockets로 이벤트를 보낼 수 있습니다.
사용자 계정을 삭제하는 사이트를 보여줍니다.
사용자 계정 삭제 및 /login 으로 리디렉션을 저장합니다.
이 서버는 각 OAUTH 제공 업체에 대해 OAUTH 리디렉션 엔드 포인트 (리디렉션 URI)를 제공합니다.
OAUTH 요청의 콜백 엔드 포인트. 연결된 ID를 사용자에게 (또는 필요한 경우 새 사용자를 생성) 및 /account 으로 리디렉션합니다.
HTTP API 및 WebSocket API에 대해 직접 프로그래밍하기 전에 로그인 클라이언트 JavaScript 브라우저 라이브러리를 살펴 봅니다. 여기에서 실제로 볼 수 있습니다 (해당 사이트의 출처).
키 title (로그인-서버 인스턴스 제목), env ( development 또는 production 과 같은 환경), publicKey (일반적으로 RSA 공개 키) 및 algorithm (JSONWEBTOKE 알고리즘)이있는 객체를 반환합니다. 주어진 공개 키에 해당하는 개인 키는 JWT에 서명 할 때 사용됩니다.
사용 가능한 공급자 목록을 반환합니다 (민감한 정보를 제거).
현재 로그인 한 사용자를 반환합니다. 사용자가 로그인되지 않은 경우 404 오류를 반환합니다.
특정 사용자를 반환합니다. 현재 자신의 사용자 ID로 제한됩니다.
특정 사용자를 조정합니다. 동일한 사용자가 현재 로그인 한 경우에만 사용할 수 있습니다. 속성이 변경 될 수 있습니다 : name (다른 모든 것은 무시됩니다).
현재 세션을 제외한 현재 사용자의 모든 세션을 제거합니다.
SessionID :id (현재 사용자를위한 세션이 필요)로 세션을 제거합니다.
JSON 웹 토큰을 형식으로 반환합니다.
{
"token" : " <JWT> " ,
"expiresIn" : 120
}참조 : JWT.
토큰 자체에는 user 속성 (현재 로그인 한 사용자에 대한 정보가 포함되어 있거나 사용자가 로그인되지 않은 경우 NULL) 및 WebSocket 연결 내에서 인증하는 데 필요한 sessionID 속성이 포함됩니다.
Base 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 /About에서와 동일한 형식을 갖습니다)token - 사용자가 로그인 한 다음 이전 토큰이 만료되기 전에 간격으로 전송됩니다 (속성 data get /token에서와 동일한 형식을 갖습니다)authenticated - 인증을 요청할 때 성공 답변으로 보냈습니다 (아래 참조)pong ping 유형의 요청에 대한 답변으로 보냈습니다 (WebSocket이 부실 해 졌는지 여부를 결정하는 데 사용될 수 있습니다)sessionAboutToExpire 현재 연관된 세션이 만료 될 때 전송됩니다.error - WebSocket을 통해 오르플 링 된 메시지에 대한 답으로 전송됩니다 (속성 data.message 로 구성됩니다. 오류 메시지가 포함 된 관리)WebSocket에 요청을 보낼 수도 있습니다. 이것들은 또한 다음 형식으로 JSON에 인코딩 된 문자열이어야합니다.
{
"type" : " name of request "
} 이것은 Get /Token에서 획득 한 JWT를 사용하여 현재 WebSocket을 특정 세션과 연관시키는 특별 요청입니다 (Send Request Object Indress 속성 token ).
WebSocket을 로그인-서버와 다른 도메인에서 사용하는 경우 authenticate 요청이 때때로 필요합니다. 이 경우, 토큰은 API를 통해 요청해야합니다 (예 credentials: "include" 또는 옵션이 포함 된 옵션이 포함되어 withCredentials: true ). 토큰에는 암호화 된 SessionID가 포함되어 있으며 WebSocket 연결과 관련이 있습니다. 다음은 웹 응용 프로그램의 워크 플로우가 어떻게 보일 수 있는지에 대한 예입니다. 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 )
}
} ) PRS가 받아 들여졌습니다.
dev Branch를 기본으로 사용하십시오. dev 의 변경 사항은 새로운 릴리스를 위해서만 master 로 병합됩니다.관리자 만
개발 중에 dev Branch에서 작업하십시오 (또는 더 나은 기능 지점에서 개발하고 준비하면 dev 로 합병하십시오).
새 릴리스가 준비되면 (예 : 기능이 완료되고, dev 로 병합되고, 모든 테스트가 성공) 포함 된 릴리스 스크립트를 실행하십시오 ( "Patch"를 "마이너"또는 "필요한 경우"메이저 "로 바꾸십시오).
npm run release:patch이것은 :
dev 중인지 확인하십시오dev 최신 상태인지 확인하십시오npm version patch 실행 (또는 "Minor"/"Major")dev 로 푸시하십시오master 로 전환하십시오dev 의 변경 사항을 병합하십시오master 푸시하십시오dev 로 다시 전환하십시오이 실행 후 GitHub Actions는 자동으로 새로운 GitHub 릴리스 드래프트를 생성합니다. 릴리스를 수동으로 편집하고 게시하십시오.
MIT © 2019 Verbundzentrale des GBV (VZG)