11cb0ef41Sopenharmony_ci# Client certificate 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciClient certificate authentication can be configured with the `Client`, the required options are passed along through the `connect` option. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciThe client certificates must be signed by a trusted CA. The Node.js default is to trust the well-known CAs curated by Mozilla. 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciSetting the server option `requestCert: true` tells the server to request the client certificate. 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciThe server option `rejectUnauthorized: false` allows us to handle any invalid certificate errors in client code. The `authorized` property on the socket of the incoming request will show if the client certificate was valid. The `authorizationError` property will give the reason if the certificate was not valid. 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci### Client Certificate Authentication 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci```js 141cb0ef41Sopenharmony_ciconst { readFileSync } = require('fs') 151cb0ef41Sopenharmony_ciconst { join } = require('path') 161cb0ef41Sopenharmony_ciconst { createServer } = require('https') 171cb0ef41Sopenharmony_ciconst { Client } = require('undici') 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst serverOptions = { 201cb0ef41Sopenharmony_ci ca: [ 211cb0ef41Sopenharmony_ci readFileSync(join(__dirname, 'client-ca-crt.pem'), 'utf8') 221cb0ef41Sopenharmony_ci ], 231cb0ef41Sopenharmony_ci key: readFileSync(join(__dirname, 'server-key.pem'), 'utf8'), 241cb0ef41Sopenharmony_ci cert: readFileSync(join(__dirname, 'server-crt.pem'), 'utf8'), 251cb0ef41Sopenharmony_ci requestCert: true, 261cb0ef41Sopenharmony_ci rejectUnauthorized: false 271cb0ef41Sopenharmony_ci} 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciconst server = createServer(serverOptions, (req, res) => { 301cb0ef41Sopenharmony_ci // true if client cert is valid 311cb0ef41Sopenharmony_ci if(req.client.authorized === true) { 321cb0ef41Sopenharmony_ci console.log('valid') 331cb0ef41Sopenharmony_ci } else { 341cb0ef41Sopenharmony_ci console.error(req.client.authorizationError) 351cb0ef41Sopenharmony_ci } 361cb0ef41Sopenharmony_ci res.end() 371cb0ef41Sopenharmony_ci}) 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciserver.listen(0, function () { 401cb0ef41Sopenharmony_ci const tls = { 411cb0ef41Sopenharmony_ci ca: [ 421cb0ef41Sopenharmony_ci readFileSync(join(__dirname, 'server-ca-crt.pem'), 'utf8') 431cb0ef41Sopenharmony_ci ], 441cb0ef41Sopenharmony_ci key: readFileSync(join(__dirname, 'client-key.pem'), 'utf8'), 451cb0ef41Sopenharmony_ci cert: readFileSync(join(__dirname, 'client-crt.pem'), 'utf8'), 461cb0ef41Sopenharmony_ci rejectUnauthorized: false, 471cb0ef41Sopenharmony_ci servername: 'agent1' 481cb0ef41Sopenharmony_ci } 491cb0ef41Sopenharmony_ci const client = new Client(`https://localhost:${server.address().port}`, { 501cb0ef41Sopenharmony_ci connect: tls 511cb0ef41Sopenharmony_ci }) 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci client.request({ 541cb0ef41Sopenharmony_ci path: '/', 551cb0ef41Sopenharmony_ci method: 'GET' 561cb0ef41Sopenharmony_ci }, (err, { body }) => { 571cb0ef41Sopenharmony_ci body.on('data', (buf) => {}) 581cb0ef41Sopenharmony_ci body.on('end', () => { 591cb0ef41Sopenharmony_ci client.close() 601cb0ef41Sopenharmony_ci server.close() 611cb0ef41Sopenharmony_ci }) 621cb0ef41Sopenharmony_ci }) 631cb0ef41Sopenharmony_ci}) 641cb0ef41Sopenharmony_ci``` 65