Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

71
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ใ€ŒใŠๅ‰ใฎใ‚ณใƒผใƒ‰ใฏใ‚ดใƒŸใ ใ€ใจ่จ€ใ„ๆ”พใฃใŸๅ…ˆ่ผฉใ‚จใƒณใ‚ธใƒ‹ใ‚ขใ‚’ใ€่‡ชๅ‹•ใƒ†ใ‚นใƒˆใงๅฎŒๅ…จ่ซ–็ ดใ—ใŸ่ฉฑ

Last updated at Posted at 2025-06-25

ใ“ใฎ่จ˜ไบ‹ใฏใ€ๆŠ€่ก“็š„ใชๅพฉ่ฎๅЇใงใ™ใ€‚ใƒ‘ใƒฏใƒใƒฉๆฐ—่ณชใฎๅ…ˆ่ผฉใ‚จใƒณใ‚ธใƒ‹ใ‚ขใซๆ•ฃใ€…้ฆฌ้นฟใซใ•ใ‚Œ็ถšใ‘ใŸๆ–ฐไบบใฎๅƒ•ใŒใ€ๆœ€็ต‚็š„ใซๆŠ€่ก“ๅŠ›ใงๅฎŒๅ…จๅ‹ๅˆฉใ‚’ๅŽใ‚ใŸๅฎŸ่ฉฑใ‚’ใŠ่ฉฑใ—ใ—ใพใ™ใ€‚

็™ปๅ ดไบบ็‰ฉ

  • ๅƒ•๏ผšๅ…ฅ็คพ2ๅนด็›ฎใฎใƒใƒƒใ‚ฏใ‚จใƒณใƒ‰ใ‚จใƒณใ‚ธใƒ‹ใ‚ข
  • ็”ฐไธญๅ…ˆ่ผฉ๏ผˆไปฎๅ๏ผ‰๏ผšๅ…ฅ็คพ5ๅนด็›ฎใ€ใƒใƒผใƒ ใƒชใƒผใƒ€ใƒผๆ ผใ€ใƒ—ใƒฉใ‚คใƒ‰้ซ˜ใ‚
  • ไฝ่—ค้ƒจ้•ท๏ผˆไปฎๅ๏ผ‰๏ผš้–‹็™บ้ƒจ้•ทใ€ๆŠ€่ก“ใซ่ฉณใ—ใ„

ไบ‹ใฎ็™บ็ซฏ๏ผšใ‚ณใƒผใƒ‰ใƒฌใƒ“ใƒฅใƒผใจใ„ใ†ๅใฎๅ…ฌ้–‹ๅ‡ฆๅˆ‘

ๅ…ฅ็คพใ—ใฆ1ๅนดใŒ็ตŒใฃใŸ้ ƒใ€ๅƒ•ใŒๆ›ธใ„ใŸใƒฆใƒผใ‚ถใƒผ่ช่จผๆฉŸ่ƒฝใฎใ‚ณใƒผใƒ‰ใƒฌใƒ“ใƒฅใƒผใงไบ‹ไปถใฏ่ตทใใพใ—ใŸใ€‚

// ๅƒ•ใŒๆ›ธใ„ใŸใ‚ณใƒผใƒ‰๏ผˆๅฝ“ๆ™‚๏ผ‰
function validateUser(username, password) {
    if (!username || !password) {
        return { success: false, message: "ๅ…ฅๅŠ›ใŒไธๅฎŒๅ…จใงใ™" };
    }
    
    const user = getUserFromDB(username);
    if (!user) {
        return { success: false, message: "ใƒฆใƒผใ‚ถใƒผใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“" };
    }
    
    if (bcrypt.compareSync(password, user.hashedPassword)) {
        return { success: true, user: user };
    } else {
        return { success: false, message: "ใƒ‘ใ‚นใƒฏใƒผใƒ‰ใŒ้–“้•ใฃใฆใ„ใพใ™" };
    }
}

็”ฐไธญๅ…ˆ่ผฉใฏๅƒ•ใฎใƒ—ใƒซใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’่ฆ‹ใ‚‹ใ‚„ๅฆใ‚„ใ€ใƒใƒผใƒ ๅ…จไฝ“ใฎSlackใƒใƒฃใƒณใƒใƒซใงใ“ใ†็™บ่จ€ใ—ใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉ๏ผšใ€Œ@ๆ–ฐไบบๅ› ใ“ใฎใ‚ณใƒผใƒ‰ใฏใ‚ดใƒŸใงใ™ใญใ€‚ใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐใ‚‚ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใ‚‚ไฝ•ใ‚‚่€ƒใˆใฆใชใ„ใ€‚ใ“ใ‚“ใชใ‚ณใƒผใƒ‰ใ‚’ๆœฌ็•ชใซไธŠใ’ใ‚‹ใคใ‚‚ใ‚Šใงใ™ใ‹๏ผŸๆ–ฐไบบใฎใใ›ใซ็”Ÿๆ„ๆฐ—ใซPRๅ‡บใ™ๅ‰ใซใ€ใ‚‚ใฃใจๅ‹‰ๅผทใ—ใฆใใ ใ•ใ„ใ€‚ใ€

ใƒใƒผใƒ ๅ…จๅ“กใŒ่ฆ‹ใฆใ„ใ‚‹ใƒใƒฃใƒณใƒใƒซใงใฎๅ…ฌ้–‹ๅ‡ฆๅˆ‘ใ€‚ๅƒ•ใฏ้ก”ใ‹ใ‚‰็ซใŒๅ‡บใ‚‹ๆ€ใ„ใงใ—ใŸใ€‚

ใ‚จใ‚นใ‚ซใƒฌใƒผใƒˆใ™ใ‚‹ๅซŒใŒใ‚‰ใ›

ใใ‚Œใ‹ใ‚‰็”ฐไธญๅ…ˆ่ผฉใฎๅƒ•ใธใฎ้ขจๅฝ“ใŸใ‚Šใฏๆ—ฅใซๆ—ฅใซๅผทใใชใ‚Šใพใ—ใŸใ€‚

  • ใ‚ณใƒผใƒ‰ใƒฌใƒ“ใƒฅใƒผใงใฏๅฟ…ใšใ€Œใ‚ปใƒณใ‚นใŒใชใ„ใ€ใ€ŒๅŸบ็คŽใŒใงใใฆใชใ„ใ€ใจใ‚ณใƒกใƒณใƒˆ
  • ไผš่ญฐใงใฏๅƒ•ใฎ็™บ่จ€ใ‚’้ฎใฃใฆใ€Œใใ‚Œใฏ้•ใ†ใ€ใจๅฆๅฎš
  • ๅƒ•ใŒ่ณชๅ•ใ™ใ‚‹ใจใ€Œใใ‚“ใชใ“ใจใ‚‚็Ÿฅใ‚‰ใชใ„ใฎ๏ผŸใ€ใจๅฐใƒใ‚ซใซใ—ใŸๆ…‹ๅบฆ

ใใ—ใฆๆฑบๅฎš็š„ใ ใฃใŸใฎใŒใ€3ใƒถๆœˆๅพŒใฎใƒใƒผใƒ ไผš่ญฐใงใฎใ“ใฎ็™บ่จ€ใงใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉ๏ผšใ€Œๆ–ฐไบบๅ›ใฎใ‚ณใƒผใƒ‰ใฏใ„ใคใ‚‚ใƒใ‚ฐใ ใ‚‰ใ‘ใงใ€ๅƒ•ใŒๆฏŽๅ›ž็›ดใ—ใฆใ‚ใ’ใฆใ‚‹ใ‚“ใงใ™ใ€‚ๆญฃ็›ดใ€ๆˆฆๅŠ›ใซใชใฃใฆใพใ›ใ‚“ใ€‚ใ€

ใ“ใฎๆ™‚ใ€ๅƒ•ใฏๅฟƒใฎไธญใง่ช“ใ„ใพใ—ใŸใ€‚ใ€Œ็ตถๅฏพใซ่ฆ‹่ฟ”ใ—ใฆใ‚„ใ‚‹ใ€ ใจใ€‚

ๅฏ†ใ‹ใช็‰น่จ“ๆœŸ้–“

ๅƒ•ใฏๆฏŽๆ—ฅ็ต‚้›ปใพใงๆฎ‹ใฃใฆๅ‹‰ๅผทใ—ใ€ๆŠ€่ก“ใ‚’็ฃจใใพใ—ใŸใ€‚

  • TypeScriptใฎๅž‹ๅฎ‰ๅ…จๆ€งใ‚’ๅพนๅบ•็š„ใซๅญฆ็ฟ’
  • Jest/Vitestใงใฎใƒ†ใ‚นใƒˆ้ง†ๅ‹•้–‹็™บใ‚’ใƒžใ‚นใ‚ฟใƒผ
  • ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใƒ™ใ‚นใƒˆใƒ—ใƒฉใ‚ฏใƒ†ใ‚ฃใ‚นใ‚’็ฟ’ๅพ—
  • CI/CDใƒ‘ใ‚คใƒ—ใƒฉใ‚คใƒณใฎๆง‹็ฏ‰ๆ–นๆณ•ใ‚’็ ”็ฉถ

ใใ—ใฆๅŠๅนดๅพŒใ€ใคใ„ใซใƒใƒฃใƒณใ‚นใŒ่จชใ‚Œใพใ—ใŸใ€‚

้‹ๅ‘ฝใฎๆ–ฐใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆ

ไผš็คพใฎๅŸบๅนนใ‚ทใ‚นใƒ†ใƒ ใ‚’ใƒชใƒ‹ใƒฅใƒผใ‚ขใƒซใ™ใ‚‹ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใŒๅง‹ใพใ‚‹ใ“ใจใซใชใ‚Šใ€็”ฐไธญๅ…ˆ่ผฉใจๅƒ•ใŒใƒกใ‚คใƒณใฎๆ‹…ๅฝ“่€…ใซๆŒ‡ๅใ•ใ‚Œใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉใฏ็›ธๅค‰ใ‚ใ‚‰ใšๅƒ•ใ‚’่ฆ‹ไธ‹ใ—ใŸๆ…‹ๅบฆใงใ€ใ“ใ†่จ€ใ„ใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉ๏ผšใ€Œๆ–ฐไบบๅ›ใซใฏ็ฐกๅ˜ใช็”ป้ขไฝœๆˆใ‚’ใŠไปปใ›ใ—ใพใ™ใ€‚้‡่ฆใชAPI่จญ่จˆใฏๅƒ•ใŒใ‚„ใ‚Šใพใ™ใ‹ใ‚‰ใ€‚ใ€

ใ—ใ‹ใ—ใ€ๅƒ•ใซใฏ็ง˜็ญ–ใŒใ‚ใ‚Šใพใ—ใŸใ€‚

็ง˜ๅฏ†ๅ…ตๅ™จ๏ผšๅฎŒ็’งใช่‡ชๅ‹•ใƒ†ใ‚นใƒˆ็’ฐๅขƒ

ๅƒ•ใฏๅฏ†ใ‹ใซใ€ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆๅ…จไฝ“ใ‚’ใ‚ซใƒใƒผใ™ใ‚‹ๅŒ…ๆ‹ฌ็š„ใชใƒ†ใ‚นใƒˆ็’ฐๅขƒใ‚’ๆง‹็ฏ‰ใ—ใฆใ„ใพใ—ใŸใ€‚

// ๅƒ•ใŒๅฏ†ใ‹ใซๆ›ธใ„ใฆใ„ใŸใƒ†ใ‚นใƒˆใ‚ณใƒผใƒ‰
describe('ใƒฆใƒผใ‚ถใƒผ่ช่จผAPI', () => {
  describe('็”ฐไธญๅ…ˆ่ผฉๅฎŸ่ฃ…ๅˆ†', () => {
    test('SQLใ‚คใƒณใ‚ธใ‚งใ‚ฏใ‚ทใƒงใƒณ่„†ๅผฑๆ€งใƒ†ใ‚นใƒˆ', async () => {
      const maliciousInput = "admin'; DROP TABLE users; --";
      const response = await request(app)
        .post('/api/auth')
        .send({ username: maliciousInput, password: 'test' });
      
      // ่„†ๅผฑๆ€งใŒใ‚ใ‚‹ใ“ใจใ‚’็ขบ่ช
      expect(response.status).toBe(500); // ใ‚จใƒฉใƒผใซใชใ‚‹
    });

    test('ใƒ‘ใ‚นใƒฏใƒผใƒ‰ๅนณๆ–‡ไฟๅญ˜ใƒใ‚งใƒƒใ‚ฏ', async () => {
      const user = await getUserFromDB('testuser');
      // ใพใ•ใ‹ใฎๅนณๆ–‡ไฟๅญ˜ใŒ็™บ่ฆš
      expect(user.password).not.toBe('plaintext123');
    });

    test('ใƒฌใƒผใƒˆๅˆถ้™ใƒ†ใ‚นใƒˆ', async () => {
      // 100ๅ›ž้€ฃ็ถšใงใƒชใ‚ฏใ‚จใ‚นใƒˆ
      const promises = Array(100).fill().map(() => 
        request(app).post('/api/auth').send({ username: 'test', password: 'test' })
      );
      
      const responses = await Promise.all(promises);
      // ใƒฌใƒผใƒˆๅˆถ้™ใŒๅฎŸ่ฃ…ใ•ใ‚Œใฆใ„ใชใ„
      expect(responses.every(r => r.status !== 429)).toBe(true);
    });
  });
});

ๆฑบๆˆฆใฎๆ—ฅ๏ผšใƒ‡ใƒขใƒณใ‚นใƒˆใƒฌใƒผใ‚ทใƒงใƒณ

ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฎไธญ้–“ๅ ฑๅ‘Šไผšใฎๆ—ฅใŒใ‚„ใฃใฆใใพใ—ใŸใ€‚็”ฐไธญๅ…ˆ่ผฉใฏ่‡ชไฟกๆบ€ใ€…ใงใƒ—ใƒฌใ‚ผใƒณใ‚’ๅง‹ใ‚ใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉ๏ผšใ€Œๆ–ฐไบบๅ›ใฎๆ‹…ๅฝ“ๅˆ†ใฏๆญฃ็›ดๅ“่ณชใŒๅฟƒ้…ใงใ—ใŸใŒใ€ๅƒ•ใŒใ—ใฃใ‹ใ‚Šใƒฌใƒ“ใƒฅใƒผใ—ใŸใฎใงๅคงไธˆๅคซใงใ™ใ€‚ๅƒ•ใฎๆ‹…ๅฝ“ใ—ใŸAPI้ƒจๅˆ†ใฏๅฎŒ็’งใชๅฎŸ่ฃ…ใซใชใฃใฆใ„ใพใ™ใ€‚ใ€

ใใ—ใฆๅƒ•ใฎ็•ชใŒๆฅใพใ—ใŸใ€‚

ๅƒ•๏ผšใ€Œใใ‚Œใงใฏใ€ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆๅ…จไฝ“ใฎๅ“่ณชใ‚’ๅฏ่ฆ–ๅŒ–ใ™ใ‚‹ใŸใ‚ใซใ€่‡ชๅ‹•ใƒ†ใ‚นใƒˆใฎ็ตๆžœใ‚’ใŠ่ฆ‹ใ›ใ—ใพใ™ใ€‚ใ€

ใ‚นใ‚ฏใƒชใƒผใƒณใซๆ˜ ใ—ๅ‡บใ•ใ‚ŒใŸใƒ†ใ‚นใƒˆ็ตๆžœ๏ผš

ใƒ†ใ‚นใƒˆ็ตๆžœใ‚ตใƒžใƒชใƒผ
==================
็”ฐไธญๅ…ˆ่ผฉๆ‹…ๅฝ“ๅˆ†๏ผš
โŒ ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใƒ†ใ‚นใƒˆ: 15/23 FAILED
โŒ ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใƒ†ใ‚นใƒˆ: 3/8 FAILED  
โŒ ใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐ: 12/18 FAILED

ๆ–ฐไบบๆ‹…ๅฝ“ๅˆ†๏ผš
โœ… ๅ…จใƒ†ใ‚นใƒˆ: 127/127 PASSED
โœ… ใ‚ซใƒใƒฌใƒƒใ‚ธ: 98.7%
โœ… ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใ‚นใ‚ณใ‚ข: A+

ไผš่ญฐๅฎคใŒ้™ใพใ‚Š่ฟ”ใ‚Šใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉใฎๅๆ’ƒใจๅฎŒๅ…จ่ซ–็ ด

็”ฐไธญๅ…ˆ่ผฉใฏ้ก”ใ‚’็œŸใฃ่ตคใซใ—ใฆๅ่ซ–ใ—ใพใ—ใŸใ€‚

็”ฐไธญๅ…ˆ่ผฉ๏ผšใ€Œใƒ†ใ‚นใƒˆใชใ‚“ใฆ้ฃพใ‚Šใงใ™๏ผๅฎŸ้š›ใฎๅ‹•ไฝœใŒ้‡่ฆใชใ‚“ใ ๏ผๆ–ฐไบบใฎใƒ†ใ‚นใƒˆใชใ‚“ใฆไฟก็”จใงใใชใ„๏ผใ€

ใใ“ใงๅƒ•ใฏใ€็”จๆ„ใ—ใฆใ„ใŸๆœ€ๅพŒใฎๅˆ‡ใ‚Šๆœญใ‚’ๅ‡บใ—ใพใ—ใŸใ€‚

ๅƒ•๏ผšใ€ŒใงใฏๅฎŸ้š›ใซใ€็”ฐไธญๅ…ˆ่ผฉใฎAPIใซใƒšใƒใƒˆใƒฌใƒผใ‚ทใƒงใƒณใƒ†ใ‚นใƒˆใ‚’ๅฎŸ่กŒใ—ใฆใฟใพใ—ใ‚‡ใ†ใ€‚ใ€

ใƒชใ‚ขใƒซใ‚ฟใ‚คใƒ ใงๅฎŸ่กŒใ•ใ‚Œใ‚‹ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใƒ†ใ‚นใƒˆใ€‚SQLใ‚คใƒณใ‚ธใ‚งใ‚ฏใ‚ทใƒงใƒณใ€XSSใ€CSRFใ€ใ™ในใฆใฎๆ”ปๆ’ƒใŒๆˆๅŠŸใ—ใฆใ—ใพใ„ใพใ—ใŸใ€‚

ๆฅตใ‚ใคใ‘ใฏใ€็”ฐไธญๅ…ˆ่ผฉใŒใ€Œใ‚ปใ‚ญใƒฅใ‚ขใซๅฎŸ่ฃ…ใ—ใŸใ€ใจ่ฑช่ชžใ—ใฆใ„ใŸใƒ‘ใ‚นใƒฏใƒผใƒ‰่ช่จผๆฉŸ่ƒฝใงใ€ใƒ‘ใ‚นใƒฏใƒผใƒ‰ใŒๅนณๆ–‡ใงใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใซไฟๅญ˜ใ•ใ‚Œใฆใ„ใ‚‹ใ“ใจใŒ็™บ่ฆšใ—ใŸใ“ใจใงใ—ใŸใ€‚

ไฝ่—ค้ƒจ้•ทใฎๅˆคๅฎš

ไฝ่—ค้ƒจ้•ทใŒ้‡ใ€…ใ—ใๅฃใ‚’้–‹ใใพใ—ใŸใ€‚

ไฝ่—ค้ƒจ้•ท๏ผšใ€Œ็”ฐไธญๅ›ใ€ใ“ใ‚Œใฏ็œ‹้Žใงใใชใ„ๅ•้กŒใงใ™ใ€‚ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃใƒ›ใƒผใƒซใ ใ‚‰ใ‘ใฎใ‚ณใƒผใƒ‰ใ‚’ใ€ŽๅฎŒ็’งใ€ใจ่จ€ใ„ๅผตใ‚‹ใฎใฏใ€ใ‚จใƒณใ‚ธใƒ‹ใ‚ขใจใ—ใฆใ‚ใ‚Šๅพ—ใชใ„ใ€‚ไธ€ๆ–นใ€ๆ–ฐไบบๅ›ใฎใ‚ณใƒผใƒ‰ใฏ้žๅธธใซ้ซ˜ๅ“่ณชใงใ€ใƒ†ใ‚นใƒˆ่จญ่จˆใ‚‚็ด ๆ™ดใ‚‰ใ—ใ„ใ€‚ไปŠๅพŒใ“ใฎใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฏๆ–ฐไบบๅ›ใซใƒชใƒผใƒ‰ใ—ใฆใ‚‚ใ‚‰ใ„ใพใ™ใ€‚ใ€

็”ฐไธญๅ…ˆ่ผฉใฎ้ก”ใฏ็œŸใฃ้’ใซใชใ‚Šใพใ—ใŸใ€‚

ไฝ่—ค้ƒจ้•ท๏ผšใ€Œ็”ฐไธญๅ›ใซใฏใ€ๆ–ฐไบบๅ›ใ‹ใ‚‰ใ‚ณใƒผใƒ‰ใƒฌใƒ“ใƒฅใƒผใจใƒ†ใ‚นใƒˆๆ‰‹ๆณ•ใซใคใ„ใฆๅญฆใ‚“ใงใ‚‚ใ‚‰ใ„ใพใ™ใ€‚ใ€

ๅฎŒๅ…จใซ็ซ‹ๅ ดใŒ้€†่ปขใ—ใŸ็žฌ้–“ใงใ—ใŸใ€‚

ใใฎๅพŒใฎๅฑ•้–‹

ใƒ—ใƒญใ‚ธใ‚งใ‚ฏใƒˆใฏๅƒ•ไธปๅฐŽใง้€ฒใ‚€ใ“ใจใซใชใ‚Šใ€ๅคงๆˆๅŠŸใ‚’ๅŽใ‚ใพใ—ใŸใ€‚็”ฐไธญๅ…ˆ่ผฉใฏๅƒ•ใซ้ ญใ‚’ไธ‹ใ’ใ€ๆŠ€่ก“็š„ใชใ“ใจใ‚’่ณชๅ•ใ™ใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸใ€‚

ใใ—ใฆๅŠๅนดๅพŒใ€ๅƒ•ใฏๆ˜‡้€ฒใ—ใฆใƒใƒผใƒ ใƒชใƒผใƒ€ใƒผใซใ€‚็”ฐไธญๅ…ˆ่ผฉใฏๅˆฅใฎใƒใƒผใƒ ใซ็•ฐๅ‹•ใจใชใ‚Šใพใ—ใŸใ€‚

ๆŠ€่ก“็š„ใชๅญฆใณ

ใ“ใฎ็ตŒ้จ“ใงๅญฆใ‚“ใ ใ“ใจใ‚’ใพใจใ‚ใพใ™๏ผš

1. ใƒ†ใ‚นใƒˆ้ง†ๅ‹•้–‹็™บใฎๅจๅŠ›

// Before: ใƒ†ใ‚นใƒˆใชใ—ใฎใ‚ณใƒผใƒ‰
function processPayment(amount, cardNumber) {
    // ๅฎŸ่ฃ…ใ ใ‘ใ—ใฆ็ต‚ใ‚ใ‚Š
    return chargeCreditCard(amount, cardNumber);
}

// After: ใƒ†ใ‚นใƒˆใƒ•ใ‚กใƒผใ‚นใƒˆใชใ‚ณใƒผใƒ‰
describe('ๆฑบๆธˆๅ‡ฆ็†', () => {
    test('็„กๅŠนใชใ‚ซใƒผใƒ‰็•ชๅทใงไพ‹ๅค–ใŒ็™บ็”Ÿใ™ใ‚‹', () => {
        expect(() => processPayment(1000, 'invalid')).toThrow();
    });
    
    test('้‡‘้กใŒ0ไปฅไธ‹ใงไพ‹ๅค–ใŒ็™บ็”Ÿใ™ใ‚‹', () => {
        expect(() => processPayment(-100, validCard)).toThrow();
    });
});

function processPayment(amount: number, cardNumber: string): PaymentResult {
    if (amount <= 0) throw new Error('้‡‘้กใŒ็„กๅŠนใงใ™');
    if (!isValidCardNumber(cardNumber)) throw new Error('ใ‚ซใƒผใƒ‰็•ชๅทใŒ็„กๅŠนใงใ™');
    
    return chargeCreditCard(amount, cardNumber);
}

2. ้™็š„่งฃๆžใƒ„ใƒผใƒซใฎๆดป็”จ

// ESLint + TypeScriptใงๅ“่ณชใ‚’ๆ‹…ไฟ
module.exports = {
  extends: [
    '@typescript-eslint/recommended',
    'plugin:security/recommended'
  ],
  rules: {
    'security/detect-sql-injection': 'error',
    'security/detect-xss': 'error'
  }
};

3. CI/CDใงใฎ่‡ชๅ‹•ๅ“่ณชใƒใ‚งใƒƒใ‚ฏ

# GitHub Actions
name: Quality Check
on: [pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run Tests
        run: npm test
      - name: Security Audit
        run: npm audit
      - name: Code Coverage
        run: npm run coverage

ใพใจใ‚

ๆŠ€่ก“ๅŠ›ใฏๅ˜˜ใ‚’ใคใใพใ›ใ‚“ใ€‚ๅฃใ ใ‘ใงใชใใ€ๅฎŸ้š›ใซๅ‹•ใใ‚ณใƒผใƒ‰ใ€ใƒ†ใ‚นใƒˆใ€ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃๅฏพ็ญ–ใงๅ‹่ฒ ใ™ใ‚Œใฐใ€ๅฟ…ใšๆญฃๅฝ“ใช่ฉ•ไพกใ‚’ๅ—ใ‘ใ‚‰ใ‚Œใพใ™ใ€‚

ใ‚‚ใ—ไปŠใ€็†ไธๅฐฝใชๆ‰ฑใ„ใ‚’ๅ—ใ‘ใฆใ„ใ‚‹ใ‚จใƒณใ‚ธใƒ‹ใ‚ขใฎๆ–นใŒใ„ใŸใ‚‰ใ€ๆŠ€่ก“ใ‚’็ฃจใ„ใฆใใ ใ•ใ„ใ€‚ใใ—ใฆ้ฉๅˆ‡ใชใ‚ฟใ‚คใƒŸใƒณใ‚ฐใงใ€ใใฎๆŠ€่ก“ๅŠ›ใ‚’่จผๆ˜Žใ—ใฆใใ ใ•ใ„ใ€‚

ๆœ€็ต‚็š„ใซๅ‹ใคใฎใฏใ€ๆœฌๅฝ“ใฎๆŠ€่ก“ๅŠ›ใ‚’ๆŒใฃใŸไบบใงใ™ใ€‚


โ€ปโ€ปโ€ป ๆณจ: ใ“ใฎ่จ˜ไบ‹ใฏAI่จ˜ไบ‹ใงใ™ โ€ปโ€ปโ€ป

ใ‚นใ‚ซใƒƒใจ็ณปใ‚ณใƒณใƒ†ใƒณใƒ„ใฃใฆใ‚ใ‚Šใพใ™ใ‚ˆใญใ€‚ๅ› ๆžœๅฟœๅ ฑ็š„ใจใ„ใ†ใ‹ใ€ใ‚ซใ‚ฟใƒซใ‚ทใ‚น็ณปใจใ„ใ†ใ‹ใ€‚
ใ“ใ†ใ„ใ†ใฎใฃใฆใŸใถใ‚“ไบบ้–“ใฏใฉใ†ใ—ใฆใ‚‚ๆฐ—ใซใชใฃใกใ‚ƒใ†ใ‚“ใ ใ‚ใ†ใชใƒผใจๆ€ใฃใฆใ€ใใ‚Œใ‚’ๆŠ€่ก“็ณป่จ˜ไบ‹ใงๆ›ธใ‹ใ›ใŸใ‚‰ใฉใ†ใชใ‚‹ใ‚“ใ ใ‚ใ†ใฃใฆๆ€ใฃใฆใ‚„ใฃใฆใฟใŸใฎใŒๆœฌ่จ˜ไบ‹ใงใ™ใ€‚
ใ‚„ใฃใฆใฟใŸๆ„Ÿๆƒณใงใ™ใŒใ€ใ‚„ใฃใฑใ‚Š่ชญใ‚“ใ˜ใ‚ƒใ„ใพใ™ใญใ€‚ใชใ‚“ใชใ‚“ใงใ—ใ‚‡ใ†ใญใ€‚ใชใ‚“ใ‹ๅซŒใงใ™ใ€‚ใ“ใ†ใ„ใ†ใฎ่ชญใ‚“ใ˜ใ‚ƒใ†ใฎใ€‚ใ“ใ‚Œใ‚‚ไบบ้–“ใฎๆ€งใชใฎใงใ—ใ‚‡ใ†ใ‹ใ€‚
ๆ€ใˆใฐๅคไปŠๆฑ่ฅฟใ‚นใ‚ซใƒƒใจ็ณปใ‚ณใƒณใƒ†ใƒณใƒ„ใฃใฆใ‚ใ‚Šใพใ™ใ‚ˆใญใ€‚ใ•ใ‚‹ใ‹ใซๅˆๆˆฆใ‚‚ใ‚ทใƒณใƒ‡ใƒฌใƒฉใ‚‚ใ€่จ€ใฃใฆใ—ใพใˆใฐใ‚นใ‚ซใƒƒใจ็ณปใงใ™ใ—ใ€‚
ใใ†ใ„ใ†ๆœฌ่ƒฝ็š„ใชใฎใ‚’ๅˆบๆฟ€ใ™ใ‚‹ใฎใŒๅฃฒใ‚Œใ‚‹ๅ•†ๅ“ใฃใฆใ‚„ใคใชใฎใ‹ใ‚‚ใ—ใ‚Œใชใ„ใ‘ใฉใ€ๅ€ซ็†็š„ใซใฉใ†ใชใฎใ‹ใฃใฆ่ฆ–็‚นใ‚‚ๅคงไบ‹ใ ใชใจๆ€ใ„ใพใ™ใ€‚
ใ“ใฎ่จ˜ไบ‹ใ‚‚ๅ€ซ็†็š„ใซใฉใ†ใชใ‚“ใฃใฆๆ€ใ„ใชใŒใ‚‰ๆŠ•็จฟใ—ใฆใพใ™ใ€‚AI่จ˜ไบ‹ใงใ™ใฃใฆๆ›ธใใฎใ‚‚ใ“ใฎใ‚ˆใ†ใซๆœ€ๅพŒใซๆ›ธใ„ใฆใ‚‹ใ—ใ€‚
ใพใ‚ใงใ‚‚ใ€่จ€ใ‚ใชใ„ใ‚ˆใ‚Šใฏใ„ใ„ใ‹ใชใฃใฆๆ€ใฃใŸใ‚Šใ—ใฆใพใ™ใ€‚
ใ‚นใ‚ซใƒƒใจใ—ใŸใจใ‹ใ‚คใƒฉใƒƒใจใ—ใŸใจใ‹ใ€ใ‚ณใƒกใƒณใƒˆใ„ใŸใ ใ‘ใŸใ‚‰ๅนธใ„ใงใ™ใ€‚

71
37
12

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

@RyuGotoo's pickup articles

RyuGotoo

@RyuGotoo(ใ‚ดใƒˆใ‚ฆ ใƒชใƒฅใ‚ฆ)

ITใ‚จใƒณใ‚ธใƒ‹ใ‚ขใ€‚ Webใƒใƒƒใ‚ฏใ‚จใƒณใƒ‰ใ€ๆฉŸๆขฐๅญฆ็ฟ’ใ‚ใŸใ‚Šใ‚’ใ‚„ใฃใฆใพใ™ใ€‚

Linked from these articles

Comments

ใ“ใ‚“ใช้ƒฝๅˆใฎ่‰ฏใ„ๅฑ•้–‹ใฏๆ™ฎ้€šใ‚ใ‚Šใˆใชใ„ใ‚ˆใชใจๆ€ใฃใŸใฎใงไฝœใ‚Š่ฉฑใจ่žใ„ใฆ็ดๅพ—ใ—ใพใ—ใŸใ€‚

21

ใ“ใ‚Œใฏใ‚นใ‚ซใƒƒใจAI

5

@potsunen
AIใ‚‚ใชใ‹ใชใ‹ไธŠๆ‰‹ใ„ใงใ™ใ‚ˆใญ

3

@ko1nksm
ๅฎŸ้š›ใ‚ใ‚Šใˆใชใ„ใงใ™ใ‚ˆใญใ€‚็”ฐไธญๅ…ˆ่ผฉใ‚’ๆ”พใฃใฆใŠใไบบไบ‹ใ‚‚ใ‚ใ‚Šใˆใชใ„ใ—ใ€ๅฝ“ๆ—ฅใพใง่ชฐใซใ‚‚ๅ…ฑๆœ‰ใ—ใชใ„ไธปไบบๅ…ฌใ‚‚ใ‚ใ‚Šใˆใชใ„ใ—ใ€ใƒ„ใƒƒใ‚ณใƒŸใฉใ“ใ‚ๆบ€่ผ‰ใงใ™ใ‚ˆใญ

3
2
@rabbitbeef

็ด ๆ™ดใ‚‰ใ—ใ„้€†่ปขๅЇใงใ€่ชญใ‚“ใงใ„ใฆใ‚นใ‚ซใƒƒใจใ—ใพใ—ใŸ๏ผ
ไธ€ๆ–นใงใ€ใ“ใ“ใพใงๅฎŒๆˆใ•ใ‚ŒใŸๆง‹ๆˆใƒปๅฑ•้–‹ใƒปๆŠ€่ก“็š„ใชๆ•ดๅˆๆ€งใ‚’ๆŒใคใ‚นใƒˆใƒผใƒชใƒผใ‚’่ชญใ‚€ใจใ€ใ€Œใ‚‚ใ—ใ‹ใ—ใฆAI็”Ÿๆˆใงใฏ๏ผŸใ€ใจๆ€ใฃใฆใ—ใพใ†ใปใฉใซใƒชใ‚ขใƒชใƒ†ใ‚ฃใจๆผ”ๅ‡บใฎใƒใƒฉใƒณใ‚นใŒ็ตถๅฆ™ใงใ™ใญใ€‚

ๆŠ€่ก“ใงๆญฃใ—ใ•ใ‚’่จผๆ˜Žใงใใ‚‹ใฎใฏใ‚จใƒณใ‚ธใƒ‹ใ‚ขใฎ้†้†ๅ‘ณใงใ™ใŒใ€ๅŒๆ™‚ใซใ€Œๆญฃ็พฉใฎๅใฎใ‚‚ใจใซไบบใ‚’ๅฉใๅฑใ†ใ•ใ€ใ‚‚ๆ„Ÿใ˜ใพใ—ใŸใ€‚
AIใŒๆ›ธใ‘ใฆใ—ใพใ†โ€œๆญฃใ—ใ™ใŽใ‚‹ใ‚นใƒˆใƒผใƒชใƒผโ€ใŒๅบƒใŒใ‚‹ไปŠใ ใ‹ใ‚‰ใ“ใใ€็œŸๅฎŸใจๆ„Ÿๆƒ…ใฎใƒใƒฉใƒณใ‚นใซใฏ่‡ช่ฆš็š„ใงใ„ใŸใ„ใจๆ€ใ„ใพใ—ใŸใ€‚

ใจใฆใ‚‚่€ƒใˆใ•ใ›ใ‚‰ใ‚Œใ‚‹่จ˜ไบ‹ใงใ—ใŸใ€‚ใ‚ใ‚ŠใŒใจใ†ใ”ใ–ใ„ใพใ™๏ผ

๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ๏ผ

ใจใ„ใ†๏ผก๏ผฉ็”Ÿๆˆใ•ใ‚ŒใŸๆ„Ÿๆƒณใงใ™๏ผ

ๆœ€ๅˆใฎใƒ—ใƒญใ‚ฐใƒฉใƒ ใซๅฏพใ™ใ‚‹ๅ…ทไฝ“็š„ใชใƒฌใƒ“ใƒฅใƒผๅ†…ๅฎนใŒๆ›ธใ‹ใ‚Œใฆใชใ„้ƒจๅˆ†ใงใ€Œใ‚“ใฃใ€ใฆๆ€ใฃใŸใ‘ใฉใ€AI็”Ÿๆˆใงใ—ใŸใ‹ใ€‚
ใ—ใ‹ใ—่‡ชๅˆ†ใงใ‚‚้ฉๅฝ“ใซใƒ—ใƒญใƒณใƒ—ใƒˆๅ…ฅใ‚ŒใฆไฝœใฃใฆใฟใŸใ‘ใฉใ€AIใง็‰ฉ่ชžใ‚‚ใ“ใ“ใพใงไฝœใ‚Œใกใ‚ƒใ†ใ‚“ใ ใชใใ€‚

ไปŠๅ›žใฏใพใ ๆฐ—ใฅใ‘ใ‚‹ใ‘ใฉใ€
่ชญใ‚“ใ ๆ™‚ใฎ็ฒ—ใ‚’ๆฝฐใ—ใฆใ„ใฃใŸใ‚Šไบบๆ‰‹ใฎไฟฎๆญฃใŒๅ…ฅใฃใŸใ‚‰ๆฐ—ใฅใ‹ใชใ„ใƒ‘ใ‚ฟใƒผใƒณใ‚‚ๅข—ใˆใใ†ใงใ™ใญใ€‚
Qiitaใฎใƒใ‚จใƒ ใซใ‚‚ๆ—ขใซๅคšๅˆ†ใ„ใ‚‹ใ‚“ใ ใ‚ใ†ใชใจใ‹ใ€‚

ๅฎŸ้š›ใฎ็ตŒ้จ“ใ‚’้ข็™ฝใŠใ‹ใ—ใใ‹ใ„ใŸใ‚‰ใ“ใ†ใชใ‚‹ใƒ‘ใ‚ฟใƒผใƒณใฏใ‚ใ‚‹ใงใ—ใ‚‡ใ†ใ€‚
ใ“ใฎๆ›ธใๆ–นใฎๆ˜ฏ้žใฏใƒ•ใ‚ฃใ‚ฏใ‚ทใƒงใƒณใงใชใ็พๅฎŸใฎใ‚‚ใฎใจใ—ใฆๆ›ธใใชใ‚‰้žใจใ—ใฆใ‚‚ใ€
ใ‚คใƒณใƒ—ใƒฌใƒƒใ‚ทใƒงใƒณใŒไผธใณใ‚„ใ™ใ„ใฎใฏ้žใฎใ‚„ใ‚Šๆ–นใงใ€
ใใ‚ŒใŒ็พๅฎŸใฎ็ตŒ้จ“ใจใ—ใฆ่ชค่ชๅฏ่ƒฝใช็ฏ„ๅ›ฒใงๅคง้‡็”Ÿ็”ฃใงใใ‚‹ใ“ใจใฏใ€
ใƒใƒƒใƒˆใงใฎๅ‡บๆฅไบ‹ใฎ็œŸ่ด‹ใฎๅˆคๅฎšใ‚‚ใงใใชใใชใ‚‹ใ—ใ€ใ‹ใคๆฉŸๆขฐใŒ็ฒพ็ฅžใ‚„่„ณใ‚’้–“ๆŽฅๆ“ไฝœใ‚‚ๅฏ่ƒฝใซใชใฃใŸใ‚ˆใ†ใชๅฑ…ๅฟƒๅœฐใฎๆ‚ชใ•ใฏใ‚ใ‚Šใพใ™ใญใ€‚
ๆญฃใ—ใไฝฟใ‚ใ‚Œใ‚‹ใชใ‚‰ใพใ ใ„ใ„ใ‚“ใงใ™ใ‘ใฉใ€ใใฎๆญฃใ—ใ•ใฎๅˆคๅฎš่ฃ…็ฝฎ่‡ชไฝ“ใ‚‚ๆ“ไฝœใงใใ†ใ‚‹ใฃใฆใ“ใจใงใ™ใ—ใ€‚

ใกใชใฟใซไธŠใฎๆ–‡็ซ ใฏ๏ผก๏ผฉ็”Ÿๆˆใงใฏใชใ„ใงใ™ใ€‚
ใชใ‚“ใง่ชญใฟใซใใ‹ใฃใŸใ‚‰ใ™ใ„ใพใ›ใ‚“ใ€‚

6

@rabbitbeef
ใปใ‚“ใจใ€็ฐกๅ˜ใชใƒ—ใƒญใƒณใƒ—ใƒˆใงใฑใฃใจ่ฆ‹ใ‚ใ‚Šๅพ—ใใ†ใชใฎไฝœใ‚Œใกใ‚ƒใ†ใ‚“ใงใ™ใ‚ˆใญใ€‚
ใ‚คใƒณใƒ—ใƒฌใƒƒใ‚ทใƒงใƒณใŒไผธใณใ‚„ใ™ใ„ใจใ„ใ†ใฎใฏใปใ‚“ใจใใฎ้€šใ‚Šใงใ€็งใŒๆ‰‹ใงใกใ‚ƒใ‚“ใจๆ›ธใ„ใŸๆŠ€่ก“่จ˜ไบ‹ใฏ600viewใใ‚‰ใ„ใชใฎใซใ€ใ“ใฎ่จ˜ไบ‹ใฏใ‚‚ใ†2000view่กŒใใ‚“ใงใ™ใ‚ˆใญใ€‚ใ€‚ใ€‚
็งใŒใ‚‚ใ—viewใ‚’็จผใใŸใ‚ใ ใ‘ใซQiitaใ‚’ใ‚„ใ‚‹ใจใ—ใŸใ‚‰ใ€ใ“ใ†ใ„ใ†่จ˜ไบ‹ใ‚’้‡็”ฃใ™ใ‚‹ใ ใ‚ใ†ใชใจๆ€ใ„ใพใ—ใŸใ€‚
ๆŠ€่ก“่€…ใจใ—ใฆใฎ็ŸœๆŒใจใ„ใ†ใ‹ๅ€ซ็†่ฆณใจใ„ใ†ใ‹ใ€ใใ†ใ„ใ†ใฎใ‚’ๆŒใฃใฆใ„ใชใ„ใจAIใซ่ธŠใ‚‰ใ•ใ‚Œใ‚‹ใ ใ‘ใซใชใฃใฆใ—ใพใ„ใใ†ใงใ€ๆฐ—ใ‚’ใคใ‘ใชใใ‚ƒใชใƒผใจใ‹ๆ›ธใใชใŒใ‚‰ๆ€ใฃใฆใ„ใพใ—ใŸใ€‚
ใ‚ณใƒกใƒณใƒˆใ‚ใ‚ŠใŒใจใ†ใ”ใ–ใ„ใพใ—ใŸ๏ผ

4

ใ‚ฝใƒผใ‚นใ‚ณใƒผใƒ‰ใ‚’ใฉใ†่ฆ‹ใฆใ‚‚ใ€ใƒใƒƒใ‚ฏใ‚จใƒณใƒ‰ใ‚จใƒณใ‚ธใƒ‹ใ‚ขใฎใ‚„ใ‚‹ใ‚‚ใฎใงใฏใชใ„ใจๆ€ใ„ใพใ™ใ€‚
็Ÿขใฃๅผตใ‚Šๆ€ใฃใŸใจใŠใ‚Šใงใ™ใ€‚(็ฌ‘)

2

@liufanqiita
่ฆ‹ๆŠœใ‹ใ‚Œใฆใ—ใพใ„ใพใ—ใŸ๏ผ
ใ‚„ใฏใ‚Šๆœฌ็‰ฉใฎใ‚จใƒณใ‚ธใƒ‹ใ‚ขใฎ็›ฎใฏ่ชค้ญ”ๅŒ–ใ›ใชใ„ใงใ™ใญใ€‚ใ€‚ใ€‚

1
This comment has been deleted for violation of our Terms of Service.
@totqkke

ใƒใƒƒใ‚ฏใ‚จใƒณใƒ‰ใฎใ“ใจใฏไฝ•ใ‚‚ๅˆ†ใ‹ใ‚‰ใชใ„ใชใŒใ‚‰ใ‚‚ใ€ใ“ใ‚“ใชไบบ้–“ใŒๆ”พ็ฝฎใ•ใ‚Œใฆใ‚‹็พๅ ดใˆใใ„ใช๏ผ๏ผใจๆ€ใ„ใชใŒใ‚‰่ชญใฟ้€ฒใ‚ใฆใ„ใŸใ‚‰AIใซใ‚ˆใ‚‹่จ˜ไบ‹ใงๅฎ‰ๅฟƒใ—ใพใ—ใŸโ€ฆใ€‚ใ‚ˆใ‹ใฃใŸโ€ฆใ€‚ใ“ใ‚“ใช็พๅ ดใฏๅญ˜ๅœจใ›ใ‡ใธใ‚“ใ‹ใฃใŸใ‚“ใ‚„โ€ฆใ€‚

0

@totqkke
ใปใ‚“ใจใงใ™ใญ๏ผ
ใงใ‚‚AIใฏๅŸบๆœฌ็š„ใซๅญฆ็ฟ’ใƒ‡ใƒผใ‚ฟใฎๆจกๅ€ฃใชใฎใงใ€ใ“ใฎ่จ˜ไบ‹ใŒ็”Ÿๆˆใ•ใ‚Œใฆใ—ใพใฃใŸใจใ„ใ†ใ“ใจใฏใ€ใ€ใ€

1

Let's comment your feelings that are more than good

71
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address