
本文介绍如何在 node.js 中利用 personnummer.js 库,不仅校验瑞典个人号码(personnummer)格式有效性,还进一步检查持有人是否年满18周岁,实现双重业务级验证。
本文介绍如何在 node.js 中利用 personnummer.js 库,不仅校验瑞典个人号码(personnummer)格式有效性,还进一步检查持有人是否年满18周岁,实现双重业务级验证。
在基于瑞典身份体系的 Web 应用中(如金融服务、内容访问控制或实名注册流程),仅验证个人号码格式合法是不够的——还需确保用户已成年(≥18 周岁)。personnummer.js 提供了开箱即用的解析能力,其中 Personnummer.parse(ssn).age 可精确计算当前年龄(基于出生日期和当前系统时间),为业务逻辑提供可靠依据。
以下是两种推荐实现方式,分别适用于中间件校验与 API 响应场景:
✅ 方式一:Express 中间件(统一错误处理)
适用于需抛出标准化错误、交由全局错误处理器统一响应的场景(如配合自定义 NotFoundError 类):
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
const Personnummer = require('personnummer.js');
module.exports = (req, res, next) => {
const ssn = req.query?.ssn || req.body?.personal_number || req.body?.ssn;
if (!ssn) {
return next(new NotFoundError({ message: 'Personal number is required' }, 403));
}
const valid = Personnummer.validate(ssn);
if (!valid) {
return next(new NotFoundError({ message: 'Invalid personal number format' }, 403));
}
// 解析并获取年龄(自动处理闰年、时区等细节)
const { age } = Personnummer.parse(ssn);
if (age < 18) {
return next(new NotFoundError({ message: 'Age must be 18 or older' }, 403));
}
return next(); // 验证通过,继续后续路由
};⚠️ 注意事项:
- Personnummer.parse(ssn) 在 ssn 格式非法时会抛出 Error,因此必须确保先调用 validate() 再 parse(),否则可能引发未捕获异常;
- age 返回整数(向下取整),例如 17.99 岁仍返回 17,符合法定成年判定逻辑;
- 该库默认使用本地系统时间计算年龄,生产环境建议确保服务器时区设置为 Europe/Stockholm(TZ=Europe/Stockholm)以匹配瑞典官方标准。
✅ 方式二:直接 JSON 响应(面向前端 API)
适用于需要明确区分错误类型的 RESTful 接口:
const Personnummer = require('personnummer.js');
module.exports = (req, res, next) => {
try {
const ssn = req.query?.ssn || req.body?.ssn;
if (!ssn) {
return res.status(400).json({ valid: false, message: 'Personal number is required' });
}
if (!Personnummer.validate(ssn)) {
return res.status(400).json({ valid: false, message: 'Invalid personal number format' });
}
const { age } = Personnummer.parse(ssn);
if (age < 18) {
return res.status(400).json({ valid: false, message: 'Applicant must be at least 18 years old' });
}
res.json({ valid: true, message: 'Valid personal number and age verified', age });
} catch (err) {
next(err); // 捕获 parse 过程中极罕见的内部异常(如无效日期)
}
};? 补充说明
- personnummer.js 支持 10 位(旧格式)和 12 位(含世纪前缀)瑞典个人号码,自动兼容;
- 年龄计算基于 YYYY-MM-DD 出生日期 + 当日日期,无需手动处理日期逻辑;
- 若需支持测试(如固定时间点验证),可通过 monkey patch Date.now 或使用 jest.mock('date-fns') 等方案模拟时间。
综上,将 age < 18 判断嵌入原有验证流程,既保持代码简洁,又精准满足合规性要求。务必遵循“先格式校验、再语义校验”的顺序,确保健壮性与可维护性。

















