モバイルデバイスのホットスポット経由でQRコード認証を実現する際、従来のローカルIP取得メソッドでは不十分でした。特に、ノートPCのループバックアドレスや仮想ネットワークインターフェースを返すだけでは、外部デバイスからのアクセスが不可能です。この問題を解決するには、実際の無線LAN(Wi-Fi)インターフェースの有効なIPv4アドレスを動的に特定する必要があります。
JavaのNetworkInterfaceクラスを使用して、すべてのネットワークインターフェースを列挙し、Wi-Fiに該当するインターフェースを識別します。一般的に、AndroidやWindowsのWi-Fiインターフェース名はwlan、wifi、またはethで始まることが多いため、名前でフィルタリングします。
package com.awe.awesometakeout.util;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
public class WifiAddressFetcher {
public static String findWifiIpv4Address() {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
// Wi-Fiインターフェースの名前を検出(多言語・OS対応)
String name = iface.getName().toLowerCase();
if (!name.contains("wlan") && !name.contains("wifi") && !name.contains("eth")) {
continue;
}
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
// IPv4アドレスかつローカルループバックでないものを選択
if (addr instanceof java.net.Inet4Address && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress()) {
return addr.getHostAddress();
}
}
}
} catch (Exception e) {
// ログ出力または監視用に適切に処理することを推奨
System.err.println("Wi-Fiアドレス取得中にエラー: " + e.getMessage());
}
return null;
}
}
このメソッドは、ループバックアドレスやリンクローカルアドレス(169.254.x.x)を除外し、実際のネットワークに割り当てられたIPv4アドレスのみを返します。これにより、外部デバイスからアクセス可能なIPが得られます。
次に、この機能をQRコード生成ロジックに組み込みます。従来のgetLocalIP()を置き換え、Wi-FiアドレスをURLに使用します。
@PostMapping("/qrcode")
public void generateQrCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String tempId = request.getParameter("tempId");
if (tempId == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// Wi-Fiの有効なIPv4アドレスを取得
String wifiIp = WifiAddressFetcher.findWifiIpv4Address();
if (wifiIp == null) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wi-Fi IPが取得できません");
return;
}
int uuid = RandomUtils.generateRandomNumber(6);
String loginUrl = "http://" + wifiIp + ":8080/dologin?qrid=" + tempId + "&uuid=" + uuid;
response.setContentType("text/plain");
response.getWriter().write(loginUrl);
}
この実装により、スマートフォンのホットスポット経由でPC上のアプリにアクセス可能なQRコードが生成されます。ただし、ファイアウォールの設定(例:ポート8080の受信ルール)が適切に構成されていないと、外部デバイスからの接続は拒否されます。Windowsでは「Windows Defender ファイアウォール」で「受信ルール」を追加し、TCPポート8080を許可する必要があります。