Slide 1

Slide 1 text

1)1$POGFSFODF'VLVPLB -BSBWFMͷηΩϡϦςΟ͸Ͳ͏ͳͬͯΔʁ ಥܸιʔείʔυϦʔσΟϯάɻ CZ3PLV !BEKQ

Slide 2

Slide 2 text

ࣗݾ঺հ

Slide 3

Slide 3 text

ࣗݾ঺հ ϓϩϑΟʔϧ w3PLV w1)1FSྺ೥͘Β͍ wגࣜձࣾ"%୅ද wژ౎෎ग़਎ɺେࡕࢢࡏॅ wొ࿥ηΩεϖ wғޟɺ͓ञ !BEKQ ୈ 025290 ߸

Slide 4

Slide 4 text

ࣗݾ঺հ աڈͷτʔΫ 1)1FS,BJHJ 1)1FS,BJHJ

Slide 5

Slide 5 text

ຊ೔ͷΞδΣϯμ

Slide 6

Slide 6 text

ࠓճͷझࢫ ͳͥ-BSBWFMͷηΩϡϦςΟΛֶͿͷ͔ w-BSBWFM͕΍͍ͬͯΔ͜ͱɺ΍͍ͬͯͳ͍͜ͱΛ஌Δɻ ˠ๻Βʢ࣮૷ऀʣ͕΍Δ͜ͱΛਖ਼͘͠஌Δɻ

Slide 7

Slide 7 text

ࠓճͷझࢫ ਐΊํ w8FCΞϓϦέʔγϣϯͷओཁͳ੬ऑੑΛɺͻͱͭͣͭ -BSBWFMʹ౰ͯ͸Ίͯ֬ೝ͢Δɻ wυΩϡϝϯτͰ͸ͳ͘ɺιʔείʔυϨϕϧͰ֬ೝ͢Δ

Slide 8

Slide 8 text

ࠓճͷझࢫ ओཁͳ੬ऑੑ w*1"ʮ҆શͳ΢ΣϒαΠτͷ ࡞Γํʢվఆୈ̓൛ʣʯ wʮ΢ΣϒΞϓϦέʔγϣ ϯͷηΩϡϦςΟ࣮૷ʯʹ ܝࡌ͞Ε͍ͯΔݸͷ੬ऑ ੑʹ͍ͭͯ৮Ε·͢ɻ

Slide 9

Slide 9 text

ࠓճͷझࢫ ݸͷ੬ऑੑ 42-ΠϯδΣΫγϣϯ 04ίϚϯυɾΠϯδΣΫγϣϯ ύε໊ύϥϝʔλͷະνΣοΫσΟ ϨΫτϦɾτϥόʔαϧ ηογϣϯ؅ཧͷෆඋ ΫϩεαΠτɾεΫϦϓςΟϯά $43' ΫϩεαΠτɾϦΫΤε τɾϑΥʔδΣϦ )551ϔομɾΠϯδΣΫγϣϯ ϝʔϧϔομɾΠϯδΣΫγϣϯ ΫϦοΫδϟοΩϯά όοϑΝΦʔόʔϑϩʔ ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ

Slide 10

Slide 10 text

ࠓճͷझࢫ ࠓ೔஻Βͳ͍͜ͱ w֤੬ऑੑͷৄࡉͳઆ໌ ˠಙؙຊಡΜͰͶɻ

Slide 11

Slide 11 text

42-ΠϯδΣΫγϣϯ

Slide 12

Slide 12 text

42-ΠϯδΣΫγϣϯ ֓ཁ w໰୊ͷ͋Δ42-จͷ૊ΈཱͯʹΑΓɺ߈ܸʹΑΔσʔλ ϕʔεͷෆਖ਼ૢ࡞Λ·Ͷ͘੬ऑੑɻ $user_name = $_GET['user_name']; $sql = "select * from users where user_name = '" . $user_name . "'"; $pdo->query($sql); ྫ $_GET[‘user_name’] = “a’; drop users; select ‘a”

Slide 13

Slide 13 text

42-ΠϯδΣΫγϣϯ جຊతͳରࡦ wಈతͳ42-ͷ૊Έཱͯʹ͸ɺϓϨʔεϗϧμʔΛ༻͍Δɻ ·ͨ͸ɺ਺஋౳΁ͷΩϟετ΍ݕূΛ࣮֬ʹߦ͏ɻ $user_name = $_GET['user_name']; $sql = "select * from users where user_name = ?"; $pdo->prepare($sql)->execute([$user_name]);

Slide 14

Slide 14 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶃ User::query() ->where('user_name', '=', $request->user_name) ->get(); ͜Ε͸໰୊ͳ͍ʁ

Slide 15

Slide 15 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶃ User::query() ->where('user_name', '=', $request->user_name) ->get();

Slide 16

Slide 16 text

42-ΠϯδΣΫγϣϯ a*MMVNJOBUFa%BUBCBTFa&MPRVFOUa#VJMEFSXIFSF public function where($column, $operator = null, $value = null, $boolean = 'and') { if ($column instanceof Closure && is_null($operator)) { // ུ } else { $this->query->where(...func_get_args()); } return $this; }

Slide 17

Slide 17 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa#VJMEFSXIFSF public function where($column, $operator = null, $value = null, $boolean = 'and') { // ུ $type = 'Basic'; $this->wheres[] = compact( 'type', 'column', 'operator', 'value', 'boolean' ); // ུ return $this; } ͜͜Ͱ͸ϓϩύςΟ $wheres ʹ [“type” => “Basic”, “column” => “user_name”, “operator” => “=”, “value” => ೖྗ஋, …] ͱ͍͏஋ΛೖΕ͍ͯΔ͚ͩɻ

Slide 18

Slide 18 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶃ User::query() ->where('user_name', '=', $request->user_name) ->get();

Slide 19

Slide 19 text

42-ΠϯδΣΫγϣϯ a*MMVNJOBUFa%BUBCBTFa&MPRVFOUa#VJMEFSHFU public function get($columns = ['*']) { $builder = $this->applyScopes(); if (count($models = $builder->getModels($columns)) > 0) { $models = $builder->eagerLoadRelations($models); } return $builder->getModel()->newCollection($models); }

Slide 20

Slide 20 text

42-ΠϯδΣΫγϣϯ a*MMVNJOBUFa%BUBCBTFa&MPRVFOUa#VJMEFSHFU.PEFMT public function getModels($columns = ['*']) { return $this->model->hydrate( $this->query->get($columns)->all() )->all(); }

Slide 21

Slide 21 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa#VJMEFSHFU public function get($columns = ['*']) { return collect( $this->onceWithColumns( Arr::wrap($columns), function () { return $this->processor->processSelect( $this, $this->runSelect() ); }) ); }

Slide 22

Slide 22 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa#VJMEFSSVO4FMFDU protected function runSelect() { return $this->connection->select( $this->toSql(), $this->getBindings(), ! $this->useWritePdo ); }

Slide 23

Slide 23 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa#VJMEFSUP4RM public function toSql() { $this->applyBeforeQueryCallbacks(); return $this->grammar->compileSelect($this); }

Slide 24

Slide 24 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSDPNQJMF4FMFDU public function compileSelect(Builder $query) { // ུ $sql = trim($this->concatenate( $this->compileComponents($query)) ); // ུ return $sql; }

Slide 25

Slide 25 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSDPNQJMF$PNQPOFOUT protected function compileComponents(Builder $query) { $sql = []; foreach ($this->selectComponents as $component) { if (isset($query->$component)) { $method = 'compile'.ucfirst($component); $sql[$component] = $this->$method( $query, $query->$component ); } } return $sql; } compileWhere()

Slide 26

Slide 26 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSDPNQJMF8IFSFT public function compileWheres(Builder $query) { // ུ if (count($sql = $this->compileWheresToArray($query)) > 0) { return $this->concatenateWhereClauses($query, $sql); } return ''; }

Slide 27

Slide 27 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSDPNQJMF8IFSFT5P"SSBZ protected function compileWheresToArray($query) { return collect($query->wheres)->map( function ($where) use ($query) { return $where['boolean'].' ‘. $this->{"where{$where['type']}"}($query, $where); } )->all(); } whereBasic()

Slide 28

Slide 28 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSXIFSF#BTJD protected function whereBasic(Builder $query, $where) { $value = $this->parameter($where['value']); $operator = str_replace('?', '??', $where['operator']); return $this->wrap($where['column']).' '.$operator.' '.$value; } “user_name = ?” ͕ return ͞ΕΔ ʹ ϓϨʔεϗϧμ͕࢖ΘΕ͍ͯΔʂ public function parameter($value) { return $this->isExpression($value) ? $this->getValue($value) : '?'; }

Slide 29

Slide 29 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶄ User::query() ->whereRaw( 'concat(first_name, last_name) like "%' . $request->user_name . '%"' ) ->get();

Slide 30

Slide 30 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶄ User::query() ->whereRaw( 'concat(first_name, last_name) like "%' . $request->user_name . '%"' ) ->get();

Slide 31

Slide 31 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa&MPRVFOUa#VJMEFS@@DBMM public function __call($method, $parameters) { // ུ $this->forwardCallTo($this->query, $method, $parameters); return $this; }

Slide 32

Slide 32 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa#VJMEFSXIFSF3BX public function whereRaw($sql, $bindings = [], $boolean = 'and') { $this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean]; $this->addBinding((array) $bindings, 'where'); return $this; } ࠓ౓͸ϓϩύςΟ $wheres ʹ [“type” => “raw”, “sql” => ‘concat("first_name", "last_name") like “%ೖྗ஋%”’, …] ͱɺೖྗ஋ΛؚΉSQL͕ͦͷ··ೖΔɻ

Slide 33

Slide 33 text

42-ΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ᶄ User::query() ->whereRaw( 'concat(first_name, last_name) like "%' . $request->user_name . '%"' ) ->get();

Slide 34

Slide 34 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSDPNQJMF8IFSFT5P"SSBZ protected function compileWheresToArray($query) { return collect($query->wheres)->map( function ($where) use ($query) { return $where['boolean'].' ‘. $this->{"where{$where['type']}"}($query, $where); } )->all(); } whereRaw() ※్த·Ͱ͸͖ͬ͞ͱಉ͡ͳͷͰলུ

Slide 35

Slide 35 text

42-ΠϯδΣΫγϣϯ *MMVNJOBUFa%BUBCBTFa2VFSZa(SBNNBSTa(SBNNBSXIFSF3BX protected function whereRaw(Builder $query, $where) { return $where['sql']; } concat(“first_name", "last_name") like “%ೖྗ஋%” ͕ͦͷ·· return ͞ΕΔʂ ʹ SQLΠϯδΣΫγϣϯ͕੒ཱ

Slide 36

Slide 36 text

42-ΠϯδΣΫγϣϯ ͜Ε͕ਖ਼ղ User::query() ->whereRaw( 'concat(first_name, last_name) like ?', ['%' . $request->user_name . '%'] ) ->get();

Slide 37

Slide 37 text

42-ΠϯδΣΫγϣϯ -BSBWFM͕΍͍ͬͯΔ͜ͱ w#VJMEFSXIFSF ͷୈҾ਺ʢҾ਺ͭͷ৔߹͸ୈҾ਺ʣ ʹೖΕͨ஋͸ɺϓϨʔεϗϧμʹม׵ͯ͘͠ΕΔɻ wͨͩ͠ɺୈҾ਺͕&YQSFTTJPO %#SBX ͳͲ ͷ৔߹ ͸ྫ֎ɻ

Slide 38

Slide 38 text

42-ΠϯδΣΫγϣϯ ๻Β͕΍Δ͜ͱ wXIFSF3BX TFMFDU3BX PSEFS#Z3BX %#SBX ͳͲΛ࢖༻͢Δࡍ͸ɺೖྗ஋Λͦͷ··ೖΕͣʹϓϨʔε ϗϧμʹ͠ɺೖྗ஋͸ୈҾ਺ CJOEJOHT ʹ౉͔͢ɺࣗ ྗͰαχλΠζ͢Δɻ

Slide 39

Slide 39 text

42-ΠϯδΣΫγϣϯ ͜Ε͸େৎ෉ʁ User::query() ->orderBy($request->orderby, $request->order) ->limit($request->limit) ->get();

Slide 40

Slide 40 text

04ίϚϯυΠϯδΣΫγ ϣϯ

Slide 41

Slide 41 text

04ίϚϯυΠϯδΣΫγϣϯ ֓ཁ wϓϩάϥϜ͔Β04ίϚϯυΛ࣮ߦ͍ͯ͠Δ৔߹ɺίϚϯ υͷ૊Έཱͯͷ໰୊ʹΑΓɺ߈ܸऀ͕ѱҙ͋ΔίϚϯυΛ ࣮ߦͰ͖ͯ͠·͏੬ऑੑɻ exec("ffmpeg -f mp4 -i {$file}");

Slide 42

Slide 42 text

04ίϚϯυΠϯδΣΫγϣϯ Ұൠతͳରࡦ wಈతʹ04ίϚϯυΛ࣮ߦ͢Δ৔߹͸ɺҾ਺Λे෼ʹνΣ οΫɺ΋͘͠͸Τεέʔϓ͢Δɻ $file = escapeshellarg($file); exec("ffmpeg -f mp4 -i {$file}");

Slide 43

Slide 43 text

04ίϚϯυΠϯδΣΫγϣϯ -BSBWFM͕΍͍ͬͯΔ͜ͱ wԿ΋ͯ͘͠Ε·ͤΜ wͨͩ͠ɺ"SUJTBODBMM ͷୈҾ਺ʹؔͯ͠͸ɺ FTDBQFTIFMMBSH Λ΍ͬͯ͘Ε͍ͯΔɻ

Slide 44

Slide 44 text

04ίϚϯυΠϯδΣΫγϣϯ ๻Β͕΍Δ͜ͱ wಈతʹ04ίϚϯυΛ࣮ߦ͢Δ৔߹͸ɺҾ਺Λे෼ʹνΣ οΫɺ΋͘͠͸Τεέʔϓ͢Δɻ

Slide 45

Slide 45 text

σΟϨΫτϦɾτϥόʔα ϧ

Slide 46

Slide 46 text

σΟϨΫτϦɾτϥόʔαϧ ֓ཁ w֎෦͔Βͷύϥϝʔλ΍63*ʹԠͯ͡ಈతʹϑΝΠϧΛಡ ΈࠐΜͰ͍Δ৔߹ʹɺ߈ܸʹΑͬͯҙਤ͠ͳ͍ϑΝΠϧΛ Ӿཡ͞Εͯ͠·͏໰୊ɻ readfile("storage/" . $_GET['file']); ྫ $_GET[‘file’] = “../.env”

Slide 47

Slide 47 text

σΟϨΫτϦɾτϥόʔαϧ Ұൠతͳରࡦ wϑΝΠϧ໊Λύϥϝʔλ౳Ͱࢦఆ͢ΔઃܭΛආ͚Δɻ ઃܭ্΍ΉΛಘͳ͍৔߹ɺݻఆͷσΟϨΫτϦΛࢦఆ͠ɺ ύϥϝʔλʹσΟϨΫτϦؚ͕·Εͳ͍Α͏ʹ͢Δɻ readfile("storage/" . basename($_GET['file']));

Slide 48

Slide 48 text

σΟϨΫτϦɾτϥόʔαϧ -BSBWFMͷ৔߹ Storage::get($request->file);

Slide 49

Slide 49 text

σΟϨΫτϦɾτϥόʔαϧ *MMVNJOBUFa'JMFTZTUFNa'JMFTZTUFN"EBQUFSHFU public function get($path) { try { return $this->driver->read($path); } catch (UnableToReadFile $e) { throw_if($this->throwsExceptions(), $e); } }

Slide 50

Slide 50 text

σΟϨΫτϦɾτϥόʔαϧ -FBHVFa'MZTZTUFNa'JMFTZTUFNSFBE public function read(string $location): string { return $this->adapter->read( $this->pathNormalizer->normalizePath($location) ); } ※ ඪ४ͷ “local” σΟεΫͷ৔߹ɺ ɹ$pathNormalizer ͸ɺ ɹLeague\Flysystem\WhitespacePathNormalizer

Slide 51

Slide 51 text

σΟϨΫτϦɾτϥόʔαϧ -FBHVFa'MZTZTUFNa8IJUFTQBDF1BUI/PSNBMJ[FSOPSNBMJ[F1BUI public function normalizePath(string $path): string { $path = str_replace('\\', '/', $path); $this->rejectFunkyWhiteSpace($path); return $this->normalizeRelativePath($path); }

Slide 52

Slide 52 text

σΟϨΫτϦɾτϥόʔαϧ -FBHVFa'MZTZTUFNa8IJUFTQBDF1BUI/PSNBMJ[FSSFKFDU'VOLZ8IJUF4QBDF private function rejectFunkyWhiteSpace(string $path): void { if (preg_match('#\p{C}+#u', $path)) { throw CorruptedPathDetected::forPath($path); } } ύεʹ੍ޚจࣈؚ͕·Ε͍ͯͨΒྫ֎Λ౤͛Δʂ

Slide 53

Slide 53 text

σΟϨΫτϦɾτϥόʔαϧ -FBHVFa'MZTZTUFNa8IJUFTQBDF1BUI/PSNBMJ[FSOPSNBMJ[F3FMBUJWF1BUI private function normalizeRelativePath(string $path): string { $parts = []; foreach (explode('/', $path) as $part) { switch ($part) { // ུ case '..': if (empty($parts)) { throw PathTraversalDetected::forPath($path); } array_pop($parts); break; // ུ } } return implode('/', $parts); } ύεʹ .. ͕͋Ε͹ྫ֎Λ౤͛Δʢ·ͨ͸আڈʣ

Slide 54

Slide 54 text

σΟϨΫτϦɾτϥόʔαϧ -BSBWFM͕΍͍ͬͯΔ͜ͱ wύεͷதʹ੍ޚจࣈ΍͕͋Ε͹ྫ֎Λεϩʔ͢Δ

Slide 55

Slide 55 text

σΟϨΫτϦɾτϥόʔαϧ ๻Β͕΍Δ͜ͱ wϑΝΠϧૢ࡞͸ՄೳͳݶΓ-BSBWFMͷ4UPSBHFΛ࢖༻͢Δɻ wͦ΋ͦ΋ϑΝΠϧ໊Λύϥϝʔλ౳Ͱࢦఆ͢ΔઃܭΛආ͚Δɻ wઃܭ্΍ΉΛಘͳ͍৔߹ɺݻఆͷσΟϨΫτϦΛࢦఆ͠ɺύϥ ϝʔλʹσΟϨΫτϦؚ͕·Εͳ͍Α͏ʹ͢Δɻ ಛʹ1)1ඪ४ͷϑΝΠϧૢ࡞ؔ਺Λ࢖༻ͤ͟ΔΛಘͳ͍৔߹ ͸ཁ஫ҙɻ

Slide 56

Slide 56 text

ηογϣϯ؅ཧͷෆඋ

Slide 57

Slide 57 text

ηογϣϯ؅ཧͷෆඋ ֓ཁ wར༻ऀͷηογϣϯ*%͕ୈࡾऀʹ஌ΒΕΔ͜ͱʹΑΓɺͦ ͷར༻ऀʹͳΓ͢·ͯ͠ΞΫηε͞ΕΔ੬ऑੑ w߈ܸྨܕ͸ଟ༷Ͱɺେผ͢Δͱɺᶃηογϣϯ*%ͷਪଌɺ ᶄηογϣϯ*%ͷ౪Έग़͠ɺᶅηογϣϯ*%ͷڧ੍ɺ ͷྨܕ͕͋Δɻ

Slide 58

Slide 58 text

ηογϣϯ؅ཧͷෆඋ Ұൠతͳରࡦ wηογϣϯ*%Λਪଌࠔ೉ͳ΋ͷʹ͢Δ wηογϣϯ*%Λ63-ύϥϝʔλʹ֨ೲ͠ͳ͍ʢ$PPLJFʹ อଘ͢Δʣ wೝূ੒ޭ࣌ʹηογϣϯ*%Λมߋ͢Δ wೝূલʹ͸ηογϣϯม਺ʹൿີ৘ใΛอଘ͠ͳ͍

Slide 59

Slide 59 text

ηογϣϯ؅ཧͷෆඋ Ұൠతͳରࡦ session.use_only_cookies = 1 session_start(); session_regenerate_id(true); ϩάΠϯ࣌ɺ·ͨ͸ϦΫΤετ͝ͱʹ session_regenerate_id() Λίʔϧ͢Δ͜ͱʹΑΓɺηογϣϯIDΛมߋɻ php.ini URL͔ΒηογϣϯIDΛड͚औΒͳ͍ɻ

Slide 60

Slide 60 text

ηογϣϯ؅ཧͷෆඋ -BSBWFMͷ৔߹ TFTTJPO@TUBSU తͳ΍ͭ͸Ͳ͜ʹɾɾɾʁ

Slide 61

Slide 61 text

ηογϣϯ؅ཧͷෆඋ "QQa)UUQa,FSOFM˞-BSBWFMY protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], // ུ ];

Slide 62

Slide 62 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOIBOEMF public function handle($request, Closure $next) { // ུ $session = $this->getSession($request); // ུ return $this->handleStatefulRequest($request, $session, $next); }

Slide 63

Slide 63 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOIBOEMF public function handle($request, Closure $next) { // ུ $session = $this->getSession($request); // ུ return $this->handleStatefulRequest($request, $session, $next); }

Slide 64

Slide 64 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOHFU4FTTJPO public function getSession(Request $request) { return tap( $this->manager->driver(), function ($session) use ($request) { $session->setId( $request->cookies->get($session->getName() ) ); }); } config/session.php ͷ 'driver' ͕ σϑΥϧτͷ 'file' ͷ৔߹ɺ Illuminate\Session\Store ·ͨ͸ Illuminate\Session\EncryptedStore (ಉ config ͷ 'encrypt' ʹΑΔ) ΛΠϯελϯεԽͯ͠ฦ͢ɻ

Slide 65

Slide 65 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOHFU4FTTJPO public function getSession(Request $request) { return tap( $this->manager->driver(), function ($session) use ($request) { $session->setId( $request->cookies->get($session->getName() ) ); }); }

Slide 66

Slide 66 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa4UPSFTFU*E public function setId($id) { $this->id = $this->isValidId($id) ? $id : $this->generateSessionId(); } protected function generateSessionId() { return Str::random(40); }

Slide 67

Slide 67 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOIBOEMF public function handle($request, Closure $next) { // ུ $session = $this->getSession($request); // ུ return $this->handleStatefulRequest($request, $session, $next); }

Slide 68

Slide 68 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOIBOEMF4UBUFGVM3FRVFTU protected function handleStatefulRequest(Request $request, $session, Closure $next) { $request->setLaravelSession( $this->startSession($request, $session) ); // ུ }

Slide 69

Slide 69 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa.JEEMFXBSFa4UBSU4FTTJPOTUBSU4FTTJPO protected function startSession(Request $request, $session) { return tap($session, function ($session) use ($request) { $session->setRequestOnHandler($request); $session->start(); }); }

Slide 70

Slide 70 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa4UPSFTUBSU public function start() { $this->loadSession(); if (! $this->has('_token')) { $this->regenerateToken(); } return $this->started = true; }

Slide 71

Slide 71 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa4UPSFMPBE4FTTJPO protected function loadSession() { $this->attributes = array_merge( $this->attributes, $this->readFromHandler() ); $this->marshalErrorBag(); }

Slide 72

Slide 72 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa4UPSFSFBE'SPN)BOEMFS protected function readFromHandler() { if ($data = $this->handler->read($this->getId())) { // ུ } return []; } $handler ͸ɺ ηογϣϯυϥΠό͕ file ͷ৔߹͸ Illuminate\Session\FileSessionHandler ※ ৄ͘͠͸ SessionManager ݟͯɻ

Slide 73

Slide 73 text

ηογϣϯ؅ཧͷෆඋ *MMVNJOBUFa4FTTJPOa'JMF4FTTJPO)BOEMFSSFBE public function read($sessionId): string|false { if ($this->files->isFile($path = $this->path.'/'. $sessionId) && $this->files->lastModified($path) >= Carbon::now()- >subMinutes($this->minutes)->getTimestamp()) { return $this->files->sharedGet($path); } return ''; }

Slide 74

Slide 74 text

ηογϣϯ؅ཧͷෆඋ ͜͜·ͰͰΘ͔ͬͨ͜ͱ w1)1ඪ४ͷηογϣϯػߏ͸࢖ΘͣɺಠࣗϑΝΠϧ؅ཧ͠ ͍ͯΔΒ͍͠ɻ ʹQIQJOJͷηογϣϯؔ࿈ͷઃఆ͸ແҙຯɻ wηογϣϯ*%͸$PPLJF͔Β͔͠औಘ͍ͯ͠ͳ͍ɻ wηογϣϯ*%͸े෼ʹਪଌͮ͠Β͍ɻ wࣗಈతʹηογϣϯ*%ΛৼΓ௚͍ͯ͠Δؾ഑͸ͳ͍ɻ

Slide 75

Slide 75 text

ηογϣϯ؅ཧͷෆඋ -BSBWFMެࣜͷ-PHJO$POUSPMMFSͷαϯϓϧ public function authenticate(Request $request): RedirectResponse { // ུ if (Auth::attempt($credentials)) { $request->session()->regenerate(); return redirect()->intended('dashboard'); } // ུ }

Slide 76

Slide 76 text

ηογϣϯ؅ཧͷෆඋ -BSBWFM͕΍͍ͬͯΔ͜ͱ wਪଌͮ͠Β͍ηογϣϯ*%ͷੜ੒ wηογϣϯ*%ͷऔಘݩΛ$PPLJFʹݶఆ ʹ63-ύϥϝʔλʹηογϣϯ*%Λ༩͑ͯ΋ແࢹ

Slide 77

Slide 77 text

ηογϣϯ؅ཧͷෆඋ ๻Β͕΍Δ͜ͱ wೝূ੒ޭ࣌ʹηογϣϯ*%Λมߋ͢Δɻ wೝূલʹ͸ηογϣϯม਺ʹൿີ৘ใΛอଘ͠ͳ͍ɻ

Slide 78

Slide 78 text

ΫϩεαΠτɾεΫϦϓς Οϯά

Slide 79

Slide 79 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ֓ཁ w8FCϖʔδʹར༻ऀͷೖྗ಺༰౳Λग़ྗ͢Δࡍͷෆඋʹ ΑΓɺ8FCϖʔδʹεΫϦϓτ౳ΛຒΊࠐ·Εͯ͠·͏ ੬ऑੑɻ

ͷݕࡧ݁Ռ

ྫ) ?search=location.href=“http:example.com”

Slide 80

Slide 80 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ Ұൠతͳରࡦ wϢʔβೖྗ஋ͷग़ྗʹରͯ͠ɺIUNMTQFDJBMDIBST Λ͔ ͚Δɻ wอݥతʹɺશͯͷม਺ग़ྗʹର࣮͠ࢪ͢Δͷ͕ϕετɻ

ͷݕࡧ݁Ռ

※ PHP 8.1 ΑΓલ͸ɺୈ2Ҿ਺ʹ ENT_QUOTES ͕ඞཁɻ

Slide 81

Slide 81 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ -BSBWFMͷ৔߹ @if ($search)

{{ $search }} ͷݕࡧ݁Ռ

@endif return view('index', [ 'search' => $request->search, ]);

Slide 82

Slide 82 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ Կͱͳ͘஌͍ͬͯΔͱࢥ͍·͕͢ɾɾɾ w#MBEFϑΝΠϧ YYYCMBEFQIQ Λɺ1)1ͱ࣮ͯ͠ߦՄ ೳͳܗʹม׵ ίϯύΠϧ ্ͨ͠ͰಡΈࠐΜͰ͍Δɻ wຖճίϯύΠϧ͍ͯ͠Δͱ஗͍ͷͰɺม׵ޙͷϑΝΠϧΛ Ωϟογϡ͍ͯ͠Δ DBDIFϑΥϧμҎԼʹ͓͍͍ͯ Δ ɻ wม׵ݩϑΝΠϧͷλΠϜελϯϓ͕ߋ৽͞ΕΔͱ࠶ม׵ɻ

Slide 83

Slide 83 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ -BSBWFMͷ৔߹ return view('index', [ 'search' => $request->search, ]);

Slide 84

Slide 84 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ MBSBWFMGSBNFXPSLTSD*MMVNJOBUF'PVOEBUJPOIFMQFSTQIQ function view($view = null, $data = [], $mergeData = []) { $factory = app(ViewFactory::class); if (func_num_args() === 0) { return $factory; } return $factory->make($view, $data, $mergeData); }

Slide 85

Slide 85 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa'BDUPSZNBLF public function make($view, $data = [], $mergeData = []) { $path = $this->finder->find( $view = $this->normalizeName($view) ); $data = array_merge($mergeData, $this->parseData($data)); return tap($this->viewInstance($view, $path, $data), function ($view) { $this->callCreator($view); }); }

Slide 86

Slide 86 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa'BDUPSZWJFX*OTUBODF protected function viewInstance($view, $path, $data) { return new View( $this, $this->getEngineFromPath($path), $view, $path, $data ); }

Slide 87

Slide 87 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa7JFX@@DPOTUSVDU public function __construct(Factory $factory, Engine $engine, $view, $path, $data = []) { $this->view = $view; $this->path = $path; $this->engine = $engine; $this->factory = $factory; $this->data = $data instanceof Arrayable ? $data- >toArray() : (array) $data; } Ҿ਺Λ٧ΊͯΔ͚ͩɻ ͜͜Ͱ͸·ͩίϯύΠϧ͸ ͯ͠ͳͦ͞͏ɻ

Slide 88

Slide 88 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ -BSBWFMͷ৔߹ return view('index', [ 'search' => $request->search, ]); w7JFXΠϯελϯε͕ίϯτϩʔϥ͔ΒSFUVSO͞ΕΔɻ w*MMVNJOBUFa3PVUJOHa3PVUFSUP3FTQPOTF ʹΑΓɺ *MMVNJOBUFa)UUQa3FTQPOTFʹ٧ΊΒΕΔɻ

Slide 89

Slide 89 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUF3PVUJOH3PVUFSUP3FTQPOTF public static function toResponse($request, $response) { // ུ } elseif (! $response instanceof SymfonyResponse) { $response = new Response($response, 200, ['Content- Type' => 'text/html']); } // ུ return $response->prepare($request); } $response ͕ View ΦϒδΣΫτ

Slide 90

Slide 90 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa)UUQa3FTQPOTF@@DPOTUSVDU public function __construct($content = '', $status = 200, array $headers = []) { $this->headers = new ResponseHeaderBag($headers); $this->setContent($content); $this->setStatusCode($status); $this->setProtocolVersion('1.0'); }

Slide 91

Slide 91 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa)UUQa3FTQPOTFTFU$POUFOU public function setContent(mixed $content): static { // ུ elseif ($content instanceof Renderable) { $content = $content->render(); } parent::setContent($content); return $this; }

Slide 92

Slide 92 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa7JFXSFOEFS public function render(callable $callback = null) { try { $contents = $this->renderContents(); // ུ } catch (Throwable $e) { // ུ } }

Slide 93

Slide 93 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa7JFXSFOEFS$POUFOUT protected function renderContents() { $this->factory->incrementRender(); $this->factory->callComposer($this); $contents = $this->getContents(); $this->factory->decrementRender(); return $contents; }

Slide 94

Slide 94 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa7JFXHFU$POUFOUT protected function getContents() { return $this->engine->get( $this->path, $this->gatherData() ); } $engine ͸௨ৗ Illuminate\View\Engines\CompilerEngine

Slide 95

Slide 95 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa&OHJOFTa$PNQJMFS&OHJOFHFU public function get($path, array $data = []) { // ུ if (! isset($this- >compiledOrNotExpired[$path]) && $this->compiler- >isExpired($path)) { $this->compiler->compile($path); } } $compiler ͸௨ৗ Illuminate\View\Compilers\BladeCompiler

Slide 96

Slide 96 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa$PNQJMFSTa#MBEF$PNQJMFSDPNQJMF public function compile($path = null) { // ུ if (! is_null($this->cachePath)) { $contents = $this->compileString( $this->files->get($this->getPath()) ); // ུ } }

Slide 97

Slide 97 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa$PNQJMFSTa#MBEF$PNQJMFSDPNQJMF4USJOH public function compileString($value) { // ུ foreach (token_get_all($value) as $token) { $result .= is_array($token) ? $this->parseToken($token) : $token; } // ུ }

Slide 98

Slide 98 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa$PNQJMFSTa#MBEF$PNQJMFSQBSTF5PLFO protected function parseToken($token) { [$id, $content] = $token; if ($id == T_INLINE_HTML) { foreach ($this->compilers as $type) { $content = $this->{"compile{$type}"}($content); } } return $content; } ഑ྻ $compilers ͷத਎͸ ['Extensions', 'Statements', 'Echos']

Slide 99

Slide 99 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa$PNQJMFSTa$PODFSOTa$PNQJMFT&DIPTDPNQJMF&DIPT public function compileEchos($value) { foreach ($this->getEchoMethods() as $method) { $value = $this->$method($value); } return $value; } $method ͸ҎԼͷ3ͭ 'compileRawEchos' 'compileEscapedEchos' ‘compileRegularEchos'

Slide 100

Slide 100 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ *MMVNJOBUFa7JFXa$PNQJMFSTa$PODFSOTa$PNQJMFT&DIPTDPNQJMF3FHVMBS&DIPT protected function compileRegularEchos($value) { $pattern = sprintf(‘/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]); $callback = function ($matches) { $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3]; $wrapped = sprintf($this->echoFormat, $this->wrapInEchoHandler($matches[2])); return $matches[1] ? substr($matches[0], 1) : "{$whitespace}"; }; return preg_replace_callback($pattern, $callback, $value); } ɾɾɾ{{ ɾɾɾ}} {{ $search }} ͸ applyEchoHandler($search)) ?> ͱͳΔ

Slide 101

Slide 101 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ -BSBWFM͕΍͍ͬͯΔ͜ͱ w\\^^ʹࣗಈతʹF Λ͚ͭͯΤεέʔϓͯ͘͠ΕΔ

Slide 102

Slide 102 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ๻Β͕΍Δ͜ͱ w\^ͷ࢖༻Λඞཁ࠷খݶʹ͢Δɻ w\^Ͱදࣔ͢Δ஋΍ϝιου಺΋ඞཁՕॴ͸ඞͣΤεέ ʔϓPSαχλΠζɻ wΞϓϦͷίʔυʹFDIP΍QSJOU@G͸ॻ͔ͳ͍

Slide 103

Slide 103 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ΍ͬͯ͠·͍͕ͪͳϛε {!! $form->input('search', $search) !! public function input(string $name, mixed $value) { return sprintf( '', $name, old($name, $value) ); }

Slide 104

Slide 104 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ΍ͬͯ͠·͍͕ͪͳϛε {!! $form->input('search', $search) !! public function input(string $name, mixed $value) { return sprintf( '', e($name), e(old($name, $value)) ); }

Slide 105

Slide 105 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ΍ͬͯ͠·͍͕ͪͳϛε {{-- Wysiwyg ΤσΟλʹΑΓHTML͕ೖྗ͞ΕΔͨΊΤεέʔϓ ͠ͳ͍ --}} {!! $article->content !!}

Slide 106

Slide 106 text

ΫϩεαΠτɾεΫϦϓςΟϯάʢ944ʣ ΍ͬͯ͠·͍͕ͪͳϛε {{-- Wysiwyg ΤσΟλʹΑΓHTML͕ೖྗ͞ΕΔͨΊΤεέʔϓ ͠ͳ͍ --}} {!! strip_tags($article->content, $allowed) !!}

Slide 107

Slide 107 text

$43' ΫϩεαΠτɾϦΫ ΤετɾϑΥʔδΣϦ

Slide 108

Slide 108 text

$43' ֓ཁ wਖ਼نͷϦΫΤετ͔Ͳ͏͔ͷݕূෆ଍ʹΑΓɺ ѱҙ͋Δ֎෦αΠτΛܦ༝ͯ͠ɺར༻ऀ͕ҙਤʹ൓ͯ͠ॏ ཁͳॲཧΛ࣮ߦͤ͞ΒΕͯ͠·͏੬ऑੑɻ wύιίϯԕִૢ࡞ࣄ݅ wʮ͸·ͪͪΌΜʯࣄ݅

Slide 109

Slide 109 text

$43' Ұൠతͳରࡦ wϦΫΤετૹ৴ݩը໘ʹͯɺୈࡾऀ͕༧ଌෆՄೳͳτʔΫ ϯΛੜ੒͠ɺϦΫΤετͱͱ΋ʹૹ৴ɻ wϦΫΤετड৴࣌ʹɺτʔΫϯͷਖ਼౰ੑΛݕূ͢Δɻ ʢੜ੒࣌ʹηογϣϯʹ֨ೲ͓ͯ͘͠ʣ

Slide 110

Slide 110 text

$43' -BSBWFMͷ৔߹ @csrf

Slide 111

Slide 111 text

$43' -BSBWFMͷ৔߹ @csrf લষͰಡΜͩ BladeCompiler ʹΑͬͯॲཧ͞ΕΔɻ

Slide 112

Slide 112 text

$43' *MMVNJOBUFa7JFXa$PNQJMFSTa$PODFSOTa$PNQJMFT)FMQFSTDPNQJMF$TSG protected function compileCsrf() { return ''; }

Slide 113

Slide 113 text

$43' WFOEPSMBSBWFMGSBNFXPSLTSD*MMVNJOBUF'PVOEBUJPOIFMQFSTQIQ function csrf_field() { return new HtmlString(''); }

Slide 114

Slide 114 text

$43' WFOEPSMBSBWFMGSBNFXPSLTSD*MMVNJOBUF'PVOEBUJPOIFMQFSTQIQ function csrf_token() { $session = app('session'); if (isset($session)) { return $session->token(); } throw new RuntimeException('Application session store not set.'); }

Slide 115

Slide 115 text

$43' *MMVNJOBUFa4FTTJPOa4UPSF public function token() { return $this->get('_token'); } ͜͜Ͱ͸ηογϣϯ͔ΒτʔΫϯΛऔಘ͍ͯ͠Δ͚ͩͰɺ ੜ੒͸͍ͯ͠ͳ͍ɻ

Slide 116

Slide 116 text

$43' *MMVNJOBUFa4FTTJPOa4UPSF public function start() { $this->loadSession(); if (! $this->has('_token')) { $this->regenerateToken(); } return $this->started = true; } ※ ͜ͷϝιου͕ݺ͹ΕΔܦҢ͸ 4ষࢀরɻ ͜͜Ͱ΍ͬͯͨʂ

Slide 117

Slide 117 text

$43' -BSBWFMͷ৔߹ @csrf w4UBSU4FTTJPOϛυϧ΢ΣΞʹΑͬͯੜ੒͞ΕͨτʔΫϯ ͕ɺJOQVUUZQFlIJEEFOzͱͯ͠ग़ྗ͞Ε͍ͯΔɻ wͰ͸ɺτʔΫϯͷݕূ͸Ͳ͜Ͱ΍͍ͬͯΔʁ

Slide 118

Slide 118 text

$43' "QQa)UUQa,FSOFM˞-BSBWFMY protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], // ུ ];

Slide 119

Slide 119 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOIBOEMF public function handle($request, Closure $next) { if ( $this->isReading($request) || $this->runningUnitTests() || $this->inExceptArray($request) || $this->tokensMatch($request) ) { // ུ } throw new TokenMismatchException('CSRF token mismatch.'); }

Slide 120

Slide 120 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOIBOEMF public function handle($request, Closure $next) { if ( $this->isReading($request) || $this->runningUnitTests() || $this->inExceptArray($request) || $this->tokensMatch($request) ) { // ུ } throw new TokenMismatchException('CSRF token mismatch.'); }

Slide 121

Slide 121 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOJT3FBEJOH protected function isReading($request) { return in_array( $request->method(), ['HEAD', 'GET', ‘OPTIONS'] ); }

Slide 122

Slide 122 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOIBOEMF public function handle($request, Closure $next) { if ( $this->isReading($request) || $this->runningUnitTests() || $this->inExceptArray($request) || $this->tokensMatch($request) ) { // ུ } throw new TokenMismatchException('CSRF token mismatch.'); }

Slide 123

Slide 123 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOUPLFOT.BUDI protected function tokensMatch($request) { $token = $this->getTokenFromRequest($request); return is_string($request->session()->token()) && is_string($token) && hash_equals($request->session()->token(), $token); }

Slide 124

Slide 124 text

$43' a*MMVNJOBUFa'PVOEBUJPOa)UUQa.JEEMFXBSFa7FSJGZ$TSG5PLFOIBOEMF public function handle($request, Closure $next) { if ( $this->isReading($request) || $this->runningUnitTests() || $this->inExceptArray($request) || $this->tokensMatch($request) ) { // ུ } throw new TokenMismatchException('CSRF token mismatch.'); } ϦΫΤετϝιου͕ GET, HEAD, OPTIONS Ҏ֎Ͱ ϦΫΤετʹτʔΫϯ͕ແ͍ɺ ΋͘͠͸ηογϣϯͷτʔΫϯͱ Ұக͍ͯ͠ͳ͚Ε͹ྫ֎Λεϩʔ

Slide 125

Slide 125 text

$43' -BSBWFM͕΍͍ͬͯΔ͜ͱ w$43'༻τʔΫϯΛੜ੒ͯ͠ηογϣϯʹೖΕ͍ͯΔ w!DTSGσΟϨΫςΟϒͰɺ্هτʔΫϯΛૹ৴͢ΔJOQVU λάΛੜ੒͍ͯ͠Δ w1045165%&-&5&ϝιουͷશͯͷϦΫΤετʹ ର͠ɺτʔΫϯ͕ෆҰகͰ͋Ε͹ྫ֎Λεϩʔ

Slide 126

Slide 126 text

$43' ๻Β͕΍Δ͜ͱ wॏཁͳॲཧʢσʔλϕʔεͷߋ৽ɺϝʔϧͷૹ৴౳ʣ͸ ඞͣ1045165%&-&5&ϝιουͰߦ͏ɻ w7FSJGZ$TSG5PLFOϛυϧ΢ΣΞΛඞͣ༗ޮʹ͢Δɻ wෆ༻ҙʹ7FSJGZ$TSG5PLFOͷআ֎ΛߦΘͳ͍ɻ

Slide 127

Slide 127 text

)551ϔομɾΠϯδΣΫ γϣϯ

Slide 128

Slide 128 text

)551ϔομɾΠϯδΣΫγϣϯ ֓ཁ wಈతʹ)551ϨεϙϯεϔομΛੜ੒͢ΔॲཧͷෆඋʹΑ Γɺෆਖ਼ͳΫοΩʔͷੜ੒ɺෆਖ਼ͳϦμΠϨΫτɺදࣔ಺ ༰ͷվมͳͲ͕ߦΘΕΔ੬ऑੑɻ

Slide 129

Slide 129 text

)551ϔομɾΠϯδΣΫγϣϯ ֓ཁ wయܕతʹ͸ɺม਺಺ʹվߦΛؚΊΔ͜ͱʹΑΓɺҙਤ͠ͳ͍)551ϔ ομΛૹ৴͢Δύλʔϯ wͨͩ͠ɺ1)1ͷIFBEFS ؔ਺͸ෳ਺ͷϔομΛૹ৴Ͱ͖ͳ͍ͨΊɺ ͜ͷ߈ܸํ๏͸੒ཱ͠ͳ͍ʢͱࢥ͏͕ɺಙؙຊ1΋ࢀরʣɻ $POUFOU%JTQPTJUJPOBUUBDINFOU fi MFOBNF\ fi MF^ $POUFOU%JTQPTJUJPOBUUBDINFOU fi MFOBNFIPHF -PDBUJPOIUUQFYBNQMFDPN

Slide 130

Slide 130 text

)551ϔομɾΠϯδΣΫγϣϯ Ұൠతͳରࡦ w)551ϔομʢϦμΠϨΫτؚΉʣʹϢʔβ༝དྷͷ஋Λؚ Ίͳ͍ɻؚΊ͟ΔΛಘͳ͍৔߹͸ɺݫີʹνΣοΫΛߦ ͏ɻ

Slide 131

Slide 131 text

)551ϔομɾΠϯδΣΫγϣϯ -BSBWFM͕΍͍ͬͯΔ͜ͱ wಛʹͳ͠

Slide 132

Slide 132 text

)551ϔομɾΠϯδΣΫγϣϯ ๻Β͕΍Δ͜ͱ w)551ϔομʢϦμΠϨΫτؚΉʣʹϢʔβ༝དྷͷ஋Λؚ Ίͳ͍ɻؚΊ͟ΔΛಘͳ͍৔߹͸ɺݫີʹνΣοΫΛߦ ͏ɻ

Slide 133

Slide 133 text

ϝʔϧϔομɾΠϯδΣΫ γϣϯ

Slide 134

Slide 134 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ ֓ཁ wϝʔϧϔομʢ'SPNϔομͳͲʣʹϢʔβೖྗ஋ΛؚΉ ৔߹ɺೖྗ஋ͷݕূෆ଍ʹΑΓɺҙਤ͠ͳ͍ϔομ΍ຊจ Λૠೖ͞Εͯ͠·͏੬ऑੑɻ

Slide 135

Slide 135 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ ֓ཁ mb_send_mail( "[email protected]", "͓໰͍߹Θ͕ͤ͋Γ·ͨ͠", $_POST['body'], "From: " . $_POST['from'], ): bool $_POST[‘from’] ʹ "[email protected] \n BCC: [email protected]" ͷΑ͏ͳจࣈྻΛೖΕΔͱ੒ཱ

Slide 136

Slide 136 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ Ұൠతͳରࡦ wϝʔϧϔομʹϢʔβೖྗ஋ΛؚΊͳ͍ɻ w΍ΉΛಘؚͣΊΔ৔߹ɺݫີͳݕূΛߦ͏ɺվߦΛআڈ͢ Δ౳ͷରࡦΛߦ͏ɻ

Slide 137

Slide 137 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ class SampleMail extends Mailable { public function build() { return $this->from($this->email) ->subject($this->title) ->text('sample'); } }

Slide 138

Slide 138 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ class SampleMail extends Mailable { public function build() { return $this->from($this->email) ->subject($this->title) ->text('sample'); } }

Slide 139

Slide 139 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFGSPN public function from($address, $name = null) { return $this->setAddress($address, $name, 'from'); }

Slide 140

Slide 140 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFTFU"EESFTT protected function setAddress($address, $name = null, $property = 'to') { // ུ foreach ($this->addressesToArray($address, $name) as $recipient) { $recipient = $this->normalizeRecipient($recipient); $this->{$property}[] = [ 'name' => $recipient->name ?? null, 'address' => $recipient->email, ]; } // ུ } ͜͜Ͱ͸ΞυϨεͷܗࣜνΣοΫ͸΍͍ͬͯͳ͍ɻ

Slide 141

Slide 141 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFTFOE public function send($mailer) { return $this->withLocale($this->locale, function () use ($mailer) { // ུ return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) { $this->buildFrom($message) ->buildRecipients($message) ->buildSubject($message) // ུ }); }); }

Slide 142

Slide 142 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFCVJME'SPN protected function buildFrom($message) { if (! empty($this->from)) { $message->from($this->from[0]['address'], $this->from[0]['name']); } return $this; }

Slide 143

Slide 143 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.FTTBHFGSPN public function from($address, $name = null) { is_array($address) ? $this->message->from(...$address) : $this->message->from(new Address($address, (string) $name)); return $this; }

Slide 144

Slide 144 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa"EESFTT@@DPOTUSVDU public function __construct(string $address, string $name = '') { // ུ $this->address = trim($address); $this->name = trim(str_replace(["\n", "\r"], '', $name)); if (!self::$validator->isValid($this->address, class_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation())) { throw new RfcComplianceException(sprintf('Email "%s" does not comply with addr-spec of RFC 2822.', $address)); } } ΞυϨε͕ܗࣜҧ൓Ͱ͋Ε͹ྫ֎Λεϩʔ͍ͯ͠Δ FromName ͔Β΋վߦΛআڈ͍ͯ͠Δʢ੍ޚจࣈ͸ʁʣ

Slide 145

Slide 145 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.FTTBHFGSPN public function from($address, $name = null) { is_array($address) ? $this->message->from(...$address) : $this->message->from(new Address($address, (string) $name)); return $this; } ͬͪ͜ʹ΋ൈ͚͕݀͋Γͦ͏ɾɾɾ

Slide 146

Slide 146 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ -BSBWFMͷ৔߹ class SampleMail extends Mailable { public function build() { return $this->from($this->email) ->subject($this->title) ->text('sample'); } }

Slide 147

Slide 147 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFTVCKFDU public function subject($subject) { $this->subject = $subject; return $this; } ͜͜Ͱ΋ܗࣜνΣοΫ΍վߦͷআڈ͸΍͍ͬͯͳ͍ɻ

Slide 148

Slide 148 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFTFOE public function send($mailer) { return $this->withLocale($this->locale, function () use ($mailer) { // ུ return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) { $this->buildFrom($message) ->buildRecipients($message) ->buildSubject($message) // ུ }); }); }

Slide 149

Slide 149 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFCVJME4VCKFDU protected function buildSubject($message) { if ($this->subject) { $message->subject($this->subject); } else { $message- >subject(Str::title(Str::snake(class_basename($this), ' '))); } return $this; }

Slide 150

Slide 150 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.FTTBHFTVCKFDU public function subject($subject) { $this->message->subject($subject); return $this; }

Slide 151

Slide 151 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa&NBJMTVCKFDU public function subject(string $subject): static { return $this->setHeaderBody('Text', 'Subject', $subject); }

Slide 152

Slide 152 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa&NBJMTFU)FBEFS#PEZ private function setHeaderBody(string $type, string $name, $body): static { $this->getHeaders()->setHeaderBody($type, $name, $body); return $this; }

Slide 153

Slide 153 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa)FBEFSTTFU)FBEFS#PEZ public function setHeaderBody(string $type, string $name, mixed $body): void { if ($this->has($name)) { $this->get($name)->setBody($body); } else { $this->{'add'.$type.'Header'}($name, $body); } }

Slide 154

Slide 154 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa)FBEFSTBEE5FYU)FBEFS public function addTextHeader(string $name, string $value): static { return $this->add(new UnstructuredHeader($name, $value)); }

Slide 155

Slide 155 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ 4ZNGPOZa$PNQPOFOUa.JNFa)FBEFSTBEE public function add(HeaderInterface $header): static { self::checkHeaderClass($header); $header->setMaxLineLength($this->lineLength); $name = strtolower($header->getName()); if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) { throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName())); } $this->headers[$name][] = $header; return $this; } վߦΛআڈͨ͠Γྫ֎Λεϩʔͨ͠Γ͸͍ͯ͠ͳ͍ɻ

Slide 156

Slide 156 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ *MMVNJOBUFa.BJMa.BJMBCMFTFOE public function send($mailer) { return $this->withLocale($this->locale, function () use ($mailer) { // ུ return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) { $this->buildFrom($message) ->buildRecipients($message) ->buildSubject($message) // ུ }); }); } ࢒Δ͸ίί͚ͩʹϝʔϧυϥΠόґଘ ඪ४υϥΠό (smtp) Ͱ͸ɺSubject͸ Quoted-Printable Τϯίʔυ͞ΕΔͨΊɺ ߈ܸ͸੒ཱ͠ͳ͍ɻ

Slide 157

Slide 157 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ -BSBWFM͕΍͍ͬͯΔ͜ͱ wϝʔϧΞυϨεؔ࿈ͷϑΟʔϧυͷܗࣜνΣοΫ wʢϝʔϧૹ৴ϥΠϒϥϦʹΑΓʣ໊݅ͷΤϯίʔυ

Slide 158

Slide 158 text

ϝʔϧϔομɾΠϯδΣΫγϣϯ ๻Β͕΍Δ͜ͱ wͱ͸͍͑ɺϔομؔ࿈ͷ߲໨Λෆ༻ҙʹಈతʹηοτ͠ͳ ͍ɻ

Slide 159

Slide 159 text

ΫϦοΫδϟοΩϯά

Slide 160

Slide 160 text

ΫϦοΫδϟοΩϯά ֓ཁ w᠘αΠτͷϖʔδ্ʹɺ߈ܸର৅αΠτΛಁ໌Խͨ͠ JGSBNFͰॏͶͯදࣔ͠ɺϢʔβ͕ҙਤ͠ͳ͍͏ͪʹΫϦ οΫͤ͞Δ߈ܸ

Slide 161

Slide 161 text

ΫϦοΫδϟοΩϯά Ұൠతͳରࡦ wϨεϙϯεϔομͰ9GSBNFPQUJPOTΛࢦఆ͢Δ

Slide 162

Slide 162 text

ΫϦοΫδϟοΩϯά -BSBWFMͷ৔߹ Կ͔΍ͬͯ͘ΕͯΔͷ͔ɾɾɾʁ

Slide 163

Slide 163 text

ΫϦοΫδϟοΩϯά *MMVNJOBUFa)UUQa.JEEMFXBSFa'SBNF(VBSE class FrameGuard { public function handle($request, Closure $next) { $response = $next($request); $response->headers->set('X-Frame-Options', 'SAMEORIGIN', false); return $response; } }

Slide 164

Slide 164 text

ΫϦοΫδϟοΩϯά -BSBWFM͕΍͍ͬͯΔ͜ͱ w'SBNF(VBSEϛυϧ΢ΣΞ͕༻ҙ͞Ε͍ͯΔɻ ͨͩ͠σϑΥϧτͰ͸༗ޮԽ͞Ε͍ͯͳ͍ɻ

Slide 165

Slide 165 text

ΫϦοΫδϟοΩϯά ๻Β͕΍Δ͜ͱ w'SBNF(VBSEϛυϧ΢ΣΞΛ༗ޮԽ͢Δɻ w·ͨ͸ɺ8FCαʔόͷઃఆͰɺશͯͷϨεϙϯεϔομʹ 9'SBNF0QUJPOΛ͚ͭΔɻ

Slide 166

Slide 166 text

όοϑΝΦʔόʔϑϩʔ

Slide 167

Slide 167 text

όοϑΝΦʔόʔϑϩʔ ֓ཁ wϓϩάϥϜ͕֬อͨ͠ϝϞϦྖҬ֎ͷϝϞϦΛ্ॻ͖͞ Εɺ΢ΣϒαʔόଆͰ೚ҙͷίʔυΛ࣮ߦ͞ΕͨΓɺϓϦ έʔγϣϯΛҟৗऴྃͤ͞ΒΕͨΓ͢Δ੬ऑੑɻ

Slide 168

Slide 168 text

όοϑΝΦʔόʔϑϩʔ Ұൠతͳରࡦ w1)1͸௚઀ϝϞϦΛૢ࡞Ͱ͖ͳ͍ͨΊɺ͜ͷ੬ऑੑ͕ੜ· ΕΔՄೳੑ͸௿͍ʢୠ͠աڈͷόʔδϣϯʹ͸ελοΫό οϑΝΦʔόʔϑϩʔͷ੬ऑੑ͕͋ͬͨʣɻ

Slide 169

Slide 169 text

όοϑΝΦʔόʔϑϩʔ -BSBWFM͕΍͍ͬͯΔ͜ͱ wಛʹͳ͠

Slide 170

Slide 170 text

όοϑΝΦʔόʔϑϩʔ ๻Β͕΍Δ͜ͱ wಛʹͳ͠ʢ੬ऑੑͷ͋Δόʔδϣϯͷ1)1΍֦ுϞδϡʔ ϧΛ࢖༻͠ͳ͍ʣ

Slide 171

Slide 171 text

ΞΫηε੍ޚ΍ೝՄ੍ޚ ͷܽམ

Slide 172

Slide 172 text

ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ ֓ཁ wઃܭ্ͷෆඋʹΑΓɺຊདྷଞऀʢଞͷར༻ऀΛؚΉʣ͕Ξ ΫηεͰ͖ͯ͸ͳΒͳ͍σʔλʹɺଞऀ͕ΞΫηεͰ͖ͨ Γɺߋ৽Ͱ͖ͨΓͯ͠͠·͏੬ऑੑɻ ྫʣύϥϝʔλΛվ͟Μ͢Ε͹ଞਓͷσʔλ͕ӾཡͰ͖ͯ ɹɹ͠·͏ɻ

Slide 173

Slide 173 text

ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ -BSBWFM͕΍͍ͬͯΔ͜ͱ w"VUI΍(BUFͳͲɺ؆ศͳೝূɾೝՄػߏͷఏڙ

Slide 174

Slide 174 text

ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ ๻Β͕΍Δ͜ͱ wਖ਼͍͠ઃܭɺ࣮૷ɺϨϏϡʔɺςετ

Slide 175

Slide 175 text

·ͱΊ

Slide 176

Slide 176 text

ࠓճͷझࢫ ݸͷ੬ऑੑ 42-ΠϯδΣΫγϣϯ 04ίϚϯυɾΠϯδΣΫγϣϯ ύε໊ύϥϝʔλͷະνΣοΫσΟ ϨΫτϦɾτϥόʔαϧ ηογϣϯ؅ཧͷෆඋ ΫϩεαΠτɾεΫϦϓςΟϯά $43' ΫϩεαΠτɾϦΫΤε τɾϑΥʔδΣϦ )551ϔομɾΠϯδΣΫγϣϯ ϝʔϧϔομɾΠϯδΣΫγϣϯ ΫϦοΫδϟοΩϯά όοϑΝΦʔόʔϑϩʔ ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ

Slide 177

Slide 177 text

ࠓճͷझࢫ ݸͷ੬ऑੑ 42-ΠϯδΣΫγϣϯ 04ίϚϯυɾΠϯδΣΫγϣϯ ύε໊ύϥϝʔλͷະνΣοΫσΟ ϨΫτϦɾτϥόʔαϧ ηογϣϯ؅ཧͷෆඋ ΫϩεαΠτɾεΫϦϓςΟϯά $43' ΫϩεαΠτɾϦΫΤε τɾϑΥʔδΣϦ )551ϔομɾΠϯδΣΫγϣϯ ϝʔϧϔομɾΠϯδΣΫγϣϯ ΫϦοΫδϟοΩϯά όοϑΝΦʔόʔϑϩʔ ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ ˕ ✕ ˕ ˓ ˕ ˕ ˕ ̋ ˚

Slide 178

Slide 178 text

૯ׅ -BSBWFM͕΍͍ͬͯΔ͜ͱ w-BSBWFM͸ɺ944ɺ$43'ɺ42-ΠϯδΣΫγϣϯ౳ͷओ ཁͳ੬ऑੑʹରͯ͠ɺରࡦͷͨΊͷػߏΛ༻ҙͯ͘͠Εͯ ͍Δɻ w͋͘·ͰػߏͰ͋Γɺ࢖͍ํΛޡΕ͹੬ऑੑ͸ੜ·ΕΔɻ wશͯͷ੬ऑੑΛΧόʔ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍ɻ

Slide 179

Slide 179 text

૯ׅ ๻Β͕΍Δ͜ͱ wਖ਼͍͠ઃܭΛ͢Δ wͦͷ্Ͱ-BSBWFMΛਖ਼͘͠࢖͏ wηΩϡϦςΟࢹ఺ͷϨϏϡʔͱςετ

Slide 180

Slide 180 text

૯ׅ ײ૝ w-BSBWFM͸΍ͬͺΓΑ͘Ͱ͖ͯΔ wιʔείʔυϦʔσΟϯά͸΍ͬͺΓָ͍͠

Slide 181

Slide 181 text

એ఻ ϓϩδΣΫτ޻਺؅ཧɾݪՁܭࢉπʔϧʮώτºπΩʯ IJUPUTVLJOFU

Slide 182

Slide 182 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·͢ʂ !BEKQ