
By default, feedback portal visitors are anonymous. Let them sign in with the account they already have in your product, and their votes and comments carry their name, count towards their company's revenue, and can be limited to customers. You need your own login page for this. The portal is available on the Team plan and up.
Go to Feedback portal → Portal settings → Security.
Under Access, choose a Sign-in method: Gleap SDK or Single sign-on.
Enter your Login page, for example https://app.yourdomain.com/login. Sign in on the portal sends visitors there.
Add the code shown under On your login page to that page.
Which one to pick:
Gleap SDK fits when the Gleap SDK already runs in your web app. Your login page identifies the user with the SDK and hands their Gleap session to the portal.
Single sign-on needs no Gleap SDK on your login page. Your server signs a short token for the user, and the portal turns it into their session. It's the better choice when your login page is a server-rendered page or a separate auth app.
When a visitor clicks Sign in, the portal opens your login page with a redirect parameter: the portal address to send them back to. Once they're signed in, your page sends them back to that address with proof of who they are. Always check that the redirect points to your portal before you send anyone there; the code on the settings page lists your portal's addresses for that.
On your login page, once the user is signed in and the Gleap SDK is loaded:
await Gleap.identify(user.id, { email: user.email, name: user.name }, userHash);
const { gleapId, gleapHash } = Gleap.getIdentity();
// Gleap sends visitors here with ?redirect=<portal URL>.
const back = new URL(new URLSearchParams(location.search).get('redirect'));
const portalHosts = ['feedback.yourdomain.com'];
if (!portalHosts.includes(back.host)) throw new Error('Unknown redirect');
// The session goes in the fragment: it never reaches a server log or another site.
const handover = new URL('/api/portal/session', back.origin);
handover.searchParams.set('return', back.pathname + back.search);
handover.hash = new URLSearchParams({ gleapId, gleapHash }).toString();
location.href = handover.toString();The userHash comes from your server, as in Identify users and send attributes and events. You only need it when identity verification is on. This is optional but adds more security to the whole verification process.
Single sign-on uses a Signing key. It's made from your project's identity verification secret, works for portal sign-ins only, and appears on the Security page once you pick Single sign-on: click Show signing key. Admins, managers and agents can see it. Keep it on your server, never in the browser.
On your server, after the user signed in on your login page:
import jwt from 'jsonwebtoken';
const token = jwt.sign(
{ userId: user.id, email: user.email, name: user.name },
process.env.GLEAP_PORTAL_SIGNING_KEY,
{ algorithm: 'HS256', expiresIn: '5m' },
);
// Gleap sends visitors here with ?redirect=<portal URL>.
const back = new URL(req.query.redirect);
const portalHosts = ['feedback.yourdomain.com'];
if (!portalHosts.includes(back.host)) throw new Error('Unknown redirect');
back.searchParams.set('gleapToken', token);
res.redirect(back.toString());A token is valid for one sign-in and for at most 15 minutes. userId is required; email and name fill in the contact. Any library that signs HS256 JSON Web Tokens works, in any language.
With a sign-in method set, turn on Require sign-in on the same page and visitors must sign in before they can open the portal at all. That turns a public roadmap into a customers-only one. To keep the portal public but limit who votes, comments or submits, set those Permissions to Signed-in users instead.
Choose No sign-in. Gleap asks first, because it removes your login page from the settings and the Sign in link from the portal.