我正在尝试使用 /* route handling for submission to SIGNUP page */
// this is all just front end validation, with no relation to the database. I think flash messages use that
router.post('/signup/users', (req, res, next) => {
req.checkBody('username', 'Username field cannot be empty.').notEmpty()
req.checkBody('username', 'Username must be between 4-30 characters long.').len(4, 30)
req.checkBody('email', 'The email you entered is invalid, please try again.').isEmail()
req.checkBody('email', 'Email address must be between 4-100 characters long, please try again.').len(4, 100)
req.checkBody('password', 'Password must be between 8-100 characters long.').len(8, 100)
// req.checkBody('password', 'Password must include one lowercase character, one uppercase character, a number, and a special character.').matches(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.* )(?=.*[^a-zA-Z0-9]).{8,}$/, 'i')
req.checkBody('passwordMatch', 'Password must be between 8-100 characters long.').len(8, 100)
req.checkBody('passwordMatch', 'Passwords do not match, please try again.').equals(req.body.password)
// Additional validation to ensure username is alphanumeric with underscores and dashes
req.checkBody('username', 'Username can only contain letters, numbers, or underscores.').matches(/^[A-Za-z0-9_-]+$/, 'i')
const errors = req.validationErrors()
if(errors || flashMessages.error) {
res.render('signup', {
errors: errors,
showErrors: true,
signupErrors: flashMessages.error
})
} else {
let password = req.body.password
bcrypt.hash(password, saltRounds, (err, hash) => {
user = new User()
user.username = req.body.username
user.email = req.body.email
user.password = hash
// PROBLEM STARTS HERE
user.save((err, result) => {
if(err) {
// add flash message here to let user know something was wrong!
const flashMessages = res.locals.getMessages()
console.log('flash', flashMessages)
console.log("Your error: ", err.message)
if (err.message.indexOf("duplicate key error") > -1) {
req.flash('signupErrors', "Username already in use.")
console.log(req.flash("hi"))
res.redirect('/signup')
console.log("Made it down here.")
} else {
req.flash('signupErrors', "There was a problem with your registration.")
console.log("Made it wayyyyyy down here.")
res.redirect('/signup')
}
// AND ENDS HERE
} else {
User.find({}).sort({ _id:-1 }).limit(1)
.exec((err, newuser) => {
if (err) {
console.log(err)
} else {
// logins user through passport function
req.login(newuser[0], (err) => {
if (err) {
console.log("Login error 1: " + err)
console.log("Login error 2: " + newuser[0])
console.log("Login error 3: " + newuser[0]._id)
} else {
console.log("Login sucess BULK: " + newuser[0])
console.log("Login success ._id: " + newuser[0]._id)
res.redirect('/home')
}
})
}
})
.catch(next)
}
})
})
}
})
/* route handling for submission to LOGIN page */
router.post('/login/users', passport.authenticate('local', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}))
生成JWT令牌(请参阅https://github.com/dvsekhvalnov/jose-jwt)以与Apple的基于令牌的新APN系统配合使用。
JWT编码方法要求secretKey采用Jose.JWT.encode(payload, secretKey, JwsAlgorithm.ES256, header)
格式。
这是我的代码将.p8文件从Apple转换为CngKey
对象:
CngKey
但是,在最后一行,将引发以下错误。
var privateKeyContent = System.IO.File.ReadAllText(authKeyPath);
var privateKey = privateKeyContent.Split('\n')[1];
//convert the private key to CngKey object and generate JWT
var secretKeyFile = Convert.FromBase64String(privateKey);
var secretKey = CngKey.Import(secretKeyFile, CngKeyBlobFormat.Pkcs8PrivateBlob);
输入的格式不正确,因为有一个单独的错误(当我更改blob类型时出现)。
此代码在.NET WebApi v4.6中运行。
我搜索过高和低,但无法解读此错误所指的内容。任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
原因我正在使用的.p8文件由于某种原因在其中间有换行符。记事本可能添加了它(并保存了吗?)。我按分界线拆分获取私钥,因此它截断了密钥。一旦我删除了换行符,它就可以正常工作。
如果收到error occurred during encode or decode operation
错误,请检查您的.p8(或其他)私钥是否格式错误且长度合适。
答案 1 :(得分:1)
我遇到了同样的问题。我用这个:
var privateKey = privateKeyContent.Split('\n')[1];
然后我分析从Apple下载的令牌文件。我发现文件中有更多\n
。我不确定这种格式在哪里不同或苹果改变了。
然后我使用以下代码加载令牌,工作。
实际上,我们可以直接使用这个令牌字符串。
var privateKeyContent = System.IO.File.ReadAllText(authKeyPath);
var privateKeyList = privateKeyContent.Split('\n');
int upperIndex = privateKeyList.Length;
StringBuilder sb = new StringBuilder();
for(int i= 1; i< upperIndex - 1; i++ )
{
sb.Append(privateKeyList[i]);
Debug.WriteLine(privateKeyList[i]);
}
答案 2 :(得分:1)
Apple为DeviceCheck提供的安全密钥(p8)也包含换行符。我使用以下代码来获取有效的CngKey:
var privateKeyContent = File.ReadAllText("pathToApplePrivateKey.p8");
var privateKeyList = privateKeyContent.Split('\n').ToList();
var privateKey = privateKeyList.Where((s, i) => i != 0 && i != privateKeyList.Count - 1)
.Aggregate((agg, s) => agg + s);
CngKey key = CngKey.Import(Convert.FromBase64String(privateKey), CngKeyBlobFormat.Pkcs8PrivateBlob);