Authentication
Login & Register
Players must authenticate before they can interact with the server. The flow depends on whether they have an account:
New players
New players see a title, action bar, and boss bar countdown prompting them to register:
/register <password> <confirm>
The password is validated against configurable rules:
- Length — Between
min-password-lengthandmax-password-length - Strength — If
require-strong-password: true, must contain uppercase + lowercase + number - Match — Both fields must be identical
- Not a common password —
password.refuse-commonchecks the chosen password againstpasswords.txt, beside the configuration, one per line and created on first run with a starter set. Emptying the file disables the check. Nothing is sent anywhere: length and character-class rules describe the shape of a password, a breach list describes whether it is already known — which is what actually gets accounts taken over
Passwords are hashed with PBKDF2-HMAC-SHA256, 210 000 iterations, with a 16-byte per-account random salt. Verification uses constant-time comparison to prevent timing attacks.
pbkdf2$210000$<saltBase64>$<hashBase64>
The iteration count is the point: a fast hash such as a single round of SHA-256 leaves a leaked database crackable on a GPU in minutes, salt or no salt. PBKDF2 ships with the JDK, so this costs no extra dependency.
Upgrading from an older version? Nothing to do. Accounts still holding the previous salt:sha256 hash keep working, and are re-hashed to PBKDF2 automatically the first time their owner logs in successfully — the only moment the clear-text password is available. No reset, no downtime.
Changing or resetting a password invalidates every existing session for that account, on every server.
Returning players
/login <password>
After successful login, the player is shown their last login date and IP (if show-last-login: true).
Failed attempts
After max-login-attempts failed attempts, the player is kicked. If IP rate limiting is enabled, the IP may be temporarily banned after too many failures across all accounts.
Titles, boss bar and action bar
The texts a player sees before authenticating live in lang/<code>.yml, so they follow the language setting in XCore like everything else:
| Key | Shown |
|---|---|
title-login / subtitle-login | To a player who already has an account |
title-register / subtitle-register | To a player who has to create one |
bossbar-authenticate | Until they authenticate. {time} = seconds left |
actionbar-login / actionbar-register | The reminder alternating with the boss bar |
Whether each one is shown at all, its timings and the boss bar colour stay in config.yml under login-title, login-bossbar and login-actionbar — those are not language.
These strings used to be in config.yml, which has no notion of a language: a server that set language: fr still greeted its players in English. If you had customised them, the old keys are named in the console on startup so you can copy them across.
Sessions
Sessions allow players to reconnect without re-entering their password within a configurable timeout.
- A session is created after each successful authentication (login, register, premium, bedrock)
- Sessions are stored in the
xlogin_sessionsdatabase table (UUID + IP + timestamp) - On join, XLogin checks for a valid session matching the player's UUID and IP
- Expired sessions are purged automatically every 10 minutes
# Session timeout in minutes (0 = disabled)
session-timeout: 30
Sessions are cross-server. When a session is created, a LOGIN sync message is broadcast so all servers in the network recognize it instantly.
Player Restrictions
While unauthenticated, players are completely locked down:
| Action | Behavior |
|---|---|
| Movement | Position locked (head rotation allowed) |
| Chat | Blocked |
| Commands | Only /login, /register, /2fa, /recover, /email + configured allowed commands |
| Blocks | Break/place blocked |
| Inventory | Open, click, drop, pickup, swap — all blocked |
| Combat | Damage given/received blocked |
| Vehicles/Portals | Blocked |
| Teleportation | Non-plugin teleports blocked |
| Visibility | Hidden from other players + blindness effect |
Join messages are withheld until authentication. Quit messages are hidden if the player never logged in.